@zapier/zapier-sdk-cli 0.8.3 → 0.9.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +35 -51
  3. package/dist/cli.cjs +750 -346
  4. package/dist/cli.mjs +751 -347
  5. package/dist/index.cjs +726 -336
  6. package/dist/index.mjs +727 -337
  7. package/dist/package.json +1 -1
  8. package/dist/src/plugins/add/ast-generator.d.ts +37 -0
  9. package/dist/src/plugins/add/ast-generator.js +403 -0
  10. package/dist/src/plugins/add/index.d.ts +13 -0
  11. package/dist/src/plugins/add/index.js +122 -0
  12. package/dist/src/plugins/add/schemas.d.ts +18 -0
  13. package/dist/src/plugins/add/schemas.js +19 -0
  14. package/dist/src/plugins/getLoginConfigPath/index.d.ts +15 -0
  15. package/dist/src/plugins/getLoginConfigPath/index.js +19 -0
  16. package/dist/src/plugins/getLoginConfigPath/schemas.d.ts +3 -0
  17. package/dist/src/plugins/getLoginConfigPath/schemas.js +5 -0
  18. package/dist/src/plugins/index.d.ts +2 -2
  19. package/dist/src/plugins/index.js +2 -2
  20. package/dist/src/sdk.js +3 -3
  21. package/dist/src/utils/cli-generator.js +15 -0
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/package.json +3 -3
  24. package/src/plugins/add/ast-generator.ts +777 -0
  25. package/src/plugins/add/index.test.ts +58 -0
  26. package/src/plugins/add/index.ts +187 -0
  27. package/src/plugins/add/schemas.ts +26 -0
  28. package/src/plugins/getLoginConfigPath/index.ts +45 -0
  29. package/src/plugins/getLoginConfigPath/schemas.ts +10 -0
  30. package/src/plugins/index.ts +2 -2
  31. package/src/sdk.ts +4 -4
  32. package/src/utils/cli-generator.ts +22 -0
  33. package/tsup.config.ts +1 -1
  34. package/dist/src/plugins/generateTypes/index.d.ts +0 -21
  35. package/dist/src/plugins/generateTypes/index.js +0 -312
  36. package/dist/src/plugins/generateTypes/schemas.d.ts +0 -18
  37. package/dist/src/plugins/generateTypes/schemas.js +0 -14
  38. package/dist/src/plugins/getConfigPath/index.d.ts +0 -15
  39. package/dist/src/plugins/getConfigPath/index.js +0 -19
  40. package/dist/src/plugins/getConfigPath/schemas.d.ts +0 -3
  41. package/dist/src/plugins/getConfigPath/schemas.js +0 -5
  42. package/src/plugins/generateTypes/index.ts +0 -444
  43. package/src/plugins/generateTypes/schemas.ts +0 -23
  44. package/src/plugins/getConfigPath/index.ts +0 -42
  45. package/src/plugins/getConfigPath/schemas.ts +0 -8
package/dist/cli.cjs CHANGED
@@ -14,9 +14,11 @@ var pkceChallenge = require('pkce-challenge');
14
14
  var ora = require('ora');
15
15
  var zapierSdkCliLogin = require('@zapier/zapier-sdk-cli-login');
16
16
  var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
17
+ var esbuild = require('esbuild');
17
18
  var fs = require('fs');
18
19
  var path = require('path');
19
- var esbuild = require('esbuild');
20
+ var ts = require('typescript');
21
+ var promises = require('fs/promises');
20
22
 
21
23
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
22
24
 
@@ -48,6 +50,7 @@ var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
48
50
  var ora__default = /*#__PURE__*/_interopDefault(ora);
49
51
  var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
50
52
  var path__namespace = /*#__PURE__*/_interopNamespace(path);
53
+ var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
51
54
 
52
55
  var SchemaParameterResolver = class {
53
56
  async resolveParameters(schema, providedParams, sdk2) {
@@ -214,12 +217,12 @@ var SchemaParameterResolver = class {
214
217
  }
215
218
  return this.createResolvableParameter([fieldName], baseSchema, isRequired);
216
219
  }
217
- createResolvableParameter(path3, schema, isRequired) {
218
- if (path3.length === 0) return null;
219
- const name = path3[path3.length - 1];
220
+ createResolvableParameter(path2, schema, isRequired) {
221
+ if (path2.length === 0) return null;
222
+ const name = path2[path2.length - 1];
220
223
  return {
221
224
  name,
222
- path: path3,
225
+ path: path2,
223
226
  schema,
224
227
  description: schema.description,
225
228
  isRequired
@@ -379,15 +382,15 @@ Optional fields:`));
379
382
  }
380
383
  return inputs;
381
384
  }
382
- getNestedValue(obj, path3) {
383
- return path3.reduce(
385
+ getNestedValue(obj, path2) {
386
+ return path2.reduce(
384
387
  (current, key) => current?.[key],
385
388
  obj
386
389
  );
387
390
  }
388
- setNestedValue(obj, path3, value) {
389
- const lastKey = path3[path3.length - 1];
390
- const parent = path3.slice(0, -1).reduce((current, key) => {
391
+ setNestedValue(obj, path2, value) {
392
+ const lastKey = path2[path2.length - 1];
393
+ const parent = path2.slice(0, -1).reduce((current, key) => {
391
394
  const currentObj = current;
392
395
  if (!(key in currentObj)) {
393
396
  currentObj[key] = {};
@@ -763,6 +766,7 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
763
766
  }
764
767
  function addCommand(program2, commandName, config) {
765
768
  const command = program2.command(commandName).description(config.description);
769
+ let hasPositionalArray = false;
766
770
  config.parameters.forEach((param) => {
767
771
  const kebabName = param.name.replace(/([A-Z])/g, "-$1").toLowerCase();
768
772
  if (param.hasResolver && param.required) {
@@ -770,6 +774,19 @@ function addCommand(program2, commandName, config) {
770
774
  `[${kebabName}]`,
771
775
  param.description || `${kebabName} parameter`
772
776
  );
777
+ } else if (param.required && param.type === "array" && !hasPositionalArray) {
778
+ hasPositionalArray = true;
779
+ command.argument(
780
+ `<${kebabName}...>`,
781
+ param.description || `${kebabName} parameter`
782
+ );
783
+ } else if (param.required && param.type === "array") {
784
+ const flags = [`--${kebabName}`];
785
+ const flagSignature = flags.join(", ") + ` <values...>`;
786
+ command.requiredOption(
787
+ flagSignature,
788
+ param.description || `${kebabName} parameter (required)`
789
+ );
773
790
  } else if (param.required) {
774
791
  command.argument(
775
792
  `<${kebabName}>`,
@@ -1051,28 +1068,28 @@ var client_default = api;
1051
1068
 
1052
1069
  // src/utils/getCallablePromise.ts
1053
1070
  var getCallablePromise = () => {
1054
- let resolve2 = () => {
1071
+ let resolve3 = () => {
1055
1072
  };
1056
1073
  let reject = () => {
1057
1074
  };
1058
1075
  const promise = new Promise((_resolve, _reject) => {
1059
- resolve2 = _resolve;
1076
+ resolve3 = _resolve;
1060
1077
  reject = _reject;
1061
1078
  });
1062
1079
  return {
1063
1080
  promise,
1064
- resolve: resolve2,
1081
+ resolve: resolve3,
1065
1082
  reject
1066
1083
  };
1067
1084
  };
1068
1085
  var getCallablePromise_default = getCallablePromise;
1069
1086
  var findAvailablePort = () => {
1070
- return new Promise((resolve2, reject) => {
1087
+ return new Promise((resolve3, reject) => {
1071
1088
  let portIndex = 0;
1072
1089
  const tryPort = (port) => {
1073
1090
  const server = express__default.default().listen(port, () => {
1074
1091
  server.close();
1075
- resolve2(port);
1092
+ resolve3(port);
1076
1093
  });
1077
1094
  server.on("error", (err) => {
1078
1095
  if (err.code === "EADDRINUSE") {
@@ -1162,15 +1179,15 @@ var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
1162
1179
  } finally {
1163
1180
  process.off("SIGINT", cleanup);
1164
1181
  process.off("SIGTERM", cleanup);
1165
- await new Promise((resolve2) => {
1182
+ await new Promise((resolve3) => {
1166
1183
  const timeout = setTimeout(() => {
1167
1184
  log_default.info("Server close timed out, forcing connection shutdown...");
1168
1185
  connections.forEach((conn) => conn.destroy());
1169
- resolve2();
1186
+ resolve3();
1170
1187
  }, 1e3);
1171
1188
  server.close(() => {
1172
1189
  clearTimeout(timeout);
1173
- resolve2();
1190
+ resolve3();
1174
1191
  });
1175
1192
  });
1176
1193
  }
@@ -1265,323 +1282,6 @@ var mcpPlugin = ({ context }) => {
1265
1282
  }
1266
1283
  };
1267
1284
  };
1268
- var GenerateTypesSchema = zod.z.object({
1269
- appKey: zapierSdk.AppKeyPropertySchema.describe("App key to generate SDK code for"),
1270
- authenticationId: zapierSdk.AuthenticationIdPropertySchema.optional(),
1271
- output: zapierSdk.OutputPropertySchema.optional().describe(
1272
- "Output file path (defaults to generated/<appKey>.ts)"
1273
- ),
1274
- lockFilePath: zod.z.string().optional().describe("Path to the .zapierrc lock file (defaults to .zapierrc)")
1275
- }).describe("Generate TypeScript SDK code for a specific app");
1276
- var generateTypesPlugin = ({ sdk: sdk2 }) => {
1277
- const generateTypesWithSdk = zapierSdk.createFunction(
1278
- async function generateTypesWithSdk2(options) {
1279
- return await generateTypes({ ...options, sdk: sdk2 });
1280
- },
1281
- GenerateTypesSchema
1282
- );
1283
- return {
1284
- generateTypes: generateTypesWithSdk,
1285
- context: {
1286
- meta: {
1287
- generateTypes: {
1288
- categories: ["utility"],
1289
- inputSchema: GenerateTypesSchema
1290
- }
1291
- }
1292
- }
1293
- };
1294
- };
1295
- function generateFetchMethodSignature() {
1296
- return ` /** Make authenticated HTTP requests through Zapier's Relay service */
1297
- fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
1298
- }
1299
- async function generateTypes(options) {
1300
- const {
1301
- appKey,
1302
- authenticationId,
1303
- output = `./types/${appKey}.d.ts`,
1304
- sdk: sdk2
1305
- } = options;
1306
- const { app, version } = parseAppIdentifier(appKey);
1307
- const actionsResult = await sdk2.listActions({
1308
- appKey: app
1309
- });
1310
- const actions = actionsResult.data;
1311
- if (actions.length === 0) {
1312
- const typeDefinitions2 = generateEmptyTypesFile(app, version);
1313
- if (output) {
1314
- fs__namespace.mkdirSync(path__namespace.dirname(output), { recursive: true });
1315
- fs__namespace.writeFileSync(output, typeDefinitions2, "utf8");
1316
- }
1317
- return typeDefinitions2;
1318
- }
1319
- const actionsWithFields = [];
1320
- if (authenticationId) {
1321
- for (const action of actions) {
1322
- try {
1323
- const manifestEntry = sdk2.getContext().getManifestEntry(appKey);
1324
- const fieldsResult = await sdk2.listInputFields({
1325
- // 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
1326
- appKey: manifestEntry ? appKey : action.app_key,
1327
- actionKey: action.key,
1328
- actionType: action.action_type,
1329
- authenticationId
1330
- });
1331
- const fields = fieldsResult.data.map((field) => {
1332
- const fieldObj = field;
1333
- return {
1334
- ...fieldObj,
1335
- required: fieldObj.is_required || fieldObj.required || false
1336
- };
1337
- });
1338
- actionsWithFields.push({
1339
- ...action,
1340
- inputFields: fields,
1341
- name: action.title || action.key
1342
- });
1343
- } catch {
1344
- actionsWithFields.push({
1345
- ...action,
1346
- inputFields: [],
1347
- name: action.title || action.key
1348
- });
1349
- }
1350
- }
1351
- } else {
1352
- actions.forEach((action) => {
1353
- actionsWithFields.push({
1354
- ...action,
1355
- inputFields: [],
1356
- name: action.title || action.key
1357
- });
1358
- });
1359
- }
1360
- const typeDefinitions = generateTypeDefinitions(
1361
- app,
1362
- actionsWithFields,
1363
- version
1364
- );
1365
- if (output) {
1366
- fs__namespace.mkdirSync(path__namespace.dirname(output), { recursive: true });
1367
- fs__namespace.writeFileSync(output, typeDefinitions, "utf8");
1368
- }
1369
- return typeDefinitions;
1370
- }
1371
- function parseAppIdentifier(identifier) {
1372
- const parts = identifier.split("@");
1373
- return {
1374
- app: parts[0],
1375
- version: parts[1]
1376
- };
1377
- }
1378
- function generateTypeDefinitions(appKey, actions, version) {
1379
- if (actions.length === 0) {
1380
- return generateEmptyTypesFile(appKey, version);
1381
- }
1382
- const actionsByType = actions.reduce(
1383
- (acc, action) => {
1384
- if (!acc[action.action_type]) {
1385
- acc[action.action_type] = [];
1386
- }
1387
- acc[action.action_type].push(action);
1388
- return acc;
1389
- },
1390
- {}
1391
- );
1392
- const appName = capitalize(appKey);
1393
- const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1394
- let output = `/* eslint-disable @typescript-eslint/naming-convention */
1395
- /**
1396
- * Auto-generated TypeScript types for Zapier ${appKey} actions
1397
- ${versionComment}
1398
- * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1399
- *
1400
- * Usage:
1401
- * import type { ${appName}Sdk } from './path/to/this/file'
1402
- * const sdk = createZapierSdk() as unknown as ${appName}Sdk
1403
- *
1404
- * // Direct usage (per-call auth):
1405
- * await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
1406
- *
1407
- * // Factory usage (pinned auth):
1408
- * const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
1409
- * await my${appName}.search.user_by_email({ inputs: { email } })
1410
- */
1411
-
1412
- import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
1413
- import { z } from 'zod'
1414
- import { RelayFetchSchema } from '@zapier/zapier-sdk'
1415
-
1416
- `;
1417
- actions.forEach((action) => {
1418
- if (action.inputFields.length > 0) {
1419
- const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
1420
- sanitizeActionName(action.key)
1421
- )}Inputs`;
1422
- output += `interface ${inputTypeName} {
1423
- `;
1424
- action.inputFields.forEach((field) => {
1425
- const isOptional = !field.required;
1426
- const fieldType = mapFieldTypeToTypeScript(field);
1427
- const description = field.helpText ? ` /** ${escapeComment(field.helpText)} */
1428
- ` : "";
1429
- output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}
1430
- `;
1431
- });
1432
- output += `}
1433
-
1434
- `;
1435
- }
1436
- });
1437
- Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
1438
- const typeName = `${appName}${capitalize(actionType)}Actions`;
1439
- output += `interface ${typeName} {
1440
- `;
1441
- typeActions.forEach((action) => {
1442
- const actionName = sanitizeActionName(action.key);
1443
- const description = action.description ? ` /** ${escapeComment(action.description)} */
1444
- ` : "";
1445
- if (action.inputFields.length > 0) {
1446
- const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
1447
- sanitizeActionName(action.key)
1448
- )}Inputs`;
1449
- output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>
1450
- `;
1451
- } else {
1452
- output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>
1453
- `;
1454
- }
1455
- });
1456
- output += `}
1457
-
1458
- `;
1459
- });
1460
- output += `interface ${appName}AppProxy {
1461
- `;
1462
- Object.keys(actionsByType).forEach((actionType) => {
1463
- const typeName = `${appName}${capitalize(actionType)}Actions`;
1464
- output += ` ${actionType}: ${typeName}
1465
- `;
1466
- });
1467
- output += generateFetchMethodSignature() + "\n";
1468
- output += `}
1469
-
1470
- `;
1471
- output += `interface ${appName}AppFactory {
1472
- `;
1473
- output += ` (options: { authenticationId: number }): ${appName}AppProxy
1474
- `;
1475
- output += `}
1476
-
1477
- `;
1478
- output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1479
-
1480
- `;
1481
- output += `export interface ${appName}Sdk {
1482
- `;
1483
- output += ` apps: {
1484
- `;
1485
- output += ` ${appKey}: ${appName}AppWithFactory
1486
- `;
1487
- output += ` }
1488
- `;
1489
- output += `}
1490
- `;
1491
- return output;
1492
- }
1493
- function generateEmptyTypesFile(appKey, version) {
1494
- const appName = capitalize(appKey);
1495
- const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1496
- return `/* eslint-disable @typescript-eslint/naming-convention */
1497
- /**
1498
- * Auto-generated TypeScript types for Zapier ${appKey} actions
1499
- ${versionComment}
1500
- * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1501
- *
1502
- * No actions found for this app.
1503
- */
1504
-
1505
- import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
1506
- import { z } from 'zod'
1507
- import { RelayFetchSchema } from '@zapier/zapier-sdk'
1508
-
1509
- interface ${appName}AppProxy {
1510
- // No actions available
1511
- ${generateFetchMethodSignature()}
1512
- }
1513
-
1514
- interface ${appName}AppFactory {
1515
- (options: { authenticationId: number }): ${appName}AppProxy
1516
- }
1517
-
1518
- type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1519
-
1520
- export interface ${appName}Sdk {
1521
- apps: {
1522
- ${appKey}: ${appName}AppWithFactory
1523
- }
1524
- }
1525
- `;
1526
- }
1527
- function capitalize(str) {
1528
- return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
1529
- }
1530
- function sanitizeActionName(actionKey) {
1531
- let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1532
- if (/^[0-9]/.test(sanitized)) {
1533
- sanitized = "_" + sanitized;
1534
- }
1535
- return sanitized;
1536
- }
1537
- function sanitizeFieldName(fieldKey) {
1538
- let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1539
- if (/^[0-9]/.test(sanitized)) {
1540
- sanitized = "_" + sanitized;
1541
- }
1542
- return sanitized;
1543
- }
1544
- function escapeComment(comment) {
1545
- return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
1546
- }
1547
- function mapFieldTypeToTypeScript(field) {
1548
- if (field.choices && field.choices.length > 0) {
1549
- const choiceValues = field.choices.filter(
1550
- (choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
1551
- ).map(
1552
- (choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value
1553
- );
1554
- if (choiceValues.length > 0) {
1555
- return choiceValues.join(" | ");
1556
- }
1557
- }
1558
- switch (field.type?.toLowerCase()) {
1559
- case "string":
1560
- case "text":
1561
- case "email":
1562
- case "url":
1563
- case "password":
1564
- return "string";
1565
- case "integer":
1566
- case "number":
1567
- return "number";
1568
- case "boolean":
1569
- return "boolean";
1570
- case "datetime":
1571
- case "date":
1572
- return "string";
1573
- // ISO date strings
1574
- case "file":
1575
- return "string";
1576
- // File URL or content
1577
- case "array":
1578
- return "any[]";
1579
- case "object":
1580
- return "Record<string, any>";
1581
- default:
1582
- return "string | number | boolean";
1583
- }
1584
- }
1585
1285
  var BundleCodeSchema = zod.z.object({
1586
1286
  input: zod.z.string().min(1).describe("Input TypeScript file path to bundle"),
1587
1287
  output: zapierSdk.OutputPropertySchema.optional().describe(
@@ -1673,21 +1373,725 @@ async function bundleCode(options) {
1673
1373
  );
1674
1374
  }
1675
1375
  }
1676
- var GetConfigPathSchema = zod.z.object({}).describe("Show the path to the configuration file");
1677
- var getConfigPathPlugin = () => {
1678
- const getConfigPathWithSdk = zapierSdk.createFunction(
1679
- async function getConfigPathWithSdk2(_options) {
1376
+ var GetLoginConfigPathSchema = zod.z.object({}).describe("Show the path to the login configuration file");
1377
+ var getLoginConfigPathPlugin = () => {
1378
+ const getLoginConfigPathWithSdk = zapierSdk.createFunction(
1379
+ async function getLoginConfigPathWithSdk2(_options) {
1680
1380
  return zapierSdkCliLogin.getConfigPath();
1681
1381
  },
1682
- GetConfigPathSchema
1382
+ GetLoginConfigPathSchema
1683
1383
  );
1684
1384
  return {
1685
- getConfigPath: getConfigPathWithSdk,
1385
+ getLoginConfigPath: getLoginConfigPathWithSdk,
1386
+ context: {
1387
+ meta: {
1388
+ getLoginConfigPath: {
1389
+ categories: ["utility"],
1390
+ inputSchema: GetLoginConfigPathSchema
1391
+ }
1392
+ }
1393
+ }
1394
+ };
1395
+ };
1396
+ var AddSchema = zod.z.object({
1397
+ appKeys: zod.z.array(zod.z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required"),
1398
+ authenticationIds: zod.z.array(zod.z.string()).optional().describe("Authentication IDs to use for type generation"),
1399
+ configPath: zod.z.string().optional().describe(
1400
+ `Path to Zapier config file (defaults to '${zapierSdk.DEFAULT_CONFIG_PATH}')`
1401
+ ),
1402
+ typesOutput: zod.z.string().optional().describe(
1403
+ "Directory for TypeScript type files (defaults to (src|lib|.)/zapier/apps/)"
1404
+ )
1405
+ });
1406
+ var AstTypeGenerator = class {
1407
+ constructor() {
1408
+ this.factory = ts__namespace.factory;
1409
+ this.printer = ts__namespace.createPrinter({
1410
+ newLine: ts__namespace.NewLineKind.LineFeed,
1411
+ removeComments: false,
1412
+ omitTrailingSemicolon: false
1413
+ });
1414
+ }
1415
+ /**
1416
+ * Generate TypeScript types using AST for a specific app
1417
+ */
1418
+ async generateTypes(options) {
1419
+ const { appKey, authenticationId, sdk: sdk2 } = options;
1420
+ const { app, version } = this.parseAppIdentifier(appKey);
1421
+ const actionsResult = await sdk2.listActions({
1422
+ appKey: app
1423
+ });
1424
+ const actions = actionsResult.data;
1425
+ if (actions.length === 0) {
1426
+ return this.generateEmptyTypesFile(app, version);
1427
+ }
1428
+ const actionsWithFields = [];
1429
+ if (authenticationId) {
1430
+ for (const action of actions) {
1431
+ try {
1432
+ const fieldsResult = await sdk2.listInputFields({
1433
+ appKey,
1434
+ actionKey: action.key,
1435
+ actionType: action.action_type,
1436
+ authenticationId
1437
+ });
1438
+ const fields = fieldsResult.data.map(
1439
+ (field) => {
1440
+ const fieldObj = field;
1441
+ return {
1442
+ ...fieldObj,
1443
+ required: fieldObj.is_required || fieldObj.required || false
1444
+ };
1445
+ }
1446
+ );
1447
+ actionsWithFields.push({
1448
+ ...action,
1449
+ inputFields: fields,
1450
+ name: action.title || action.key
1451
+ });
1452
+ } catch {
1453
+ actionsWithFields.push({
1454
+ ...action,
1455
+ inputFields: [],
1456
+ name: action.title || action.key
1457
+ });
1458
+ }
1459
+ }
1460
+ } else {
1461
+ actions.forEach(
1462
+ (action) => {
1463
+ actionsWithFields.push({
1464
+ ...action,
1465
+ inputFields: [],
1466
+ name: action.title || action.key,
1467
+ app_key: action.app_key || appKey,
1468
+ action_type: action.action_type || "write",
1469
+ title: action.title || action.key,
1470
+ type: "action",
1471
+ description: action.description || ""
1472
+ });
1473
+ }
1474
+ );
1475
+ }
1476
+ const sourceFile = this.createSourceFile(app, actionsWithFields, version);
1477
+ return this.printer.printFile(sourceFile);
1478
+ }
1479
+ parseAppIdentifier(identifier) {
1480
+ const parts = identifier.split("@");
1481
+ return {
1482
+ app: parts[0],
1483
+ version: parts[1]
1484
+ };
1485
+ }
1486
+ createSourceFile(appKey, actions, version) {
1487
+ const appName = this.capitalize(appKey);
1488
+ const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1489
+ const headerComment = `Auto-generated TypeScript types for Zapier ${appKey} actions
1490
+ ${versionComment.slice(3)}
1491
+ Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1492
+
1493
+ This file automatically augments the base SDK types when present.
1494
+ No manual imports or type casting required.
1495
+
1496
+ Usage:
1497
+ import { createZapierSdk } from "@zapier/zapier-sdk";
1498
+
1499
+ const zapier = createZapierSdk();
1500
+ // Types are automatically available:
1501
+ await zapier.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
1502
+
1503
+ // Factory usage (pinned auth):
1504
+ const my${appName} = zapier.apps.${appKey}({ authenticationId: 123 })
1505
+ await my${appName}.search.user_by_email({ inputs: { email } })`;
1506
+ const statements = [
1507
+ // Import the SDK to activate module augmentation
1508
+ this.createImportStatement(["@zapier/zapier-sdk"]),
1509
+ // Import types we'll use
1510
+ this.createTypeImportStatement(
1511
+ [
1512
+ "ActionExecutionOptions",
1513
+ "ActionExecutionResult",
1514
+ "ZapierFetchInitOptions"
1515
+ ],
1516
+ "@zapier/zapier-sdk"
1517
+ )
1518
+ ];
1519
+ const actionsByType = this.groupActionsByType(actions);
1520
+ actions.forEach((action) => {
1521
+ if (action.inputFields.length > 0) {
1522
+ const inputInterface = this.createInputInterface(appName, action);
1523
+ statements.push(inputInterface);
1524
+ }
1525
+ });
1526
+ Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
1527
+ const actionInterface = this.createActionInterface(
1528
+ appName,
1529
+ actionType,
1530
+ typeActions
1531
+ );
1532
+ statements.push(actionInterface);
1533
+ });
1534
+ const appProxyInterface = this.createAppProxyInterface(
1535
+ appName,
1536
+ actionsByType
1537
+ );
1538
+ statements.push(appProxyInterface);
1539
+ const appFactoryInterface = this.createAppFactoryInterface(appName);
1540
+ statements.push(appFactoryInterface);
1541
+ const appWithFactoryType = this.createAppWithFactoryType(appName);
1542
+ statements.push(appWithFactoryType);
1543
+ const moduleAugmentation = this.createModuleAugmentation(appKey, appName);
1544
+ statements.push(moduleAugmentation);
1545
+ statements.push(
1546
+ this.factory.createExportDeclaration(
1547
+ void 0,
1548
+ false,
1549
+ this.factory.createNamedExports([])
1550
+ )
1551
+ );
1552
+ const sourceFile = ts__namespace.createSourceFile(
1553
+ "generated.d.ts",
1554
+ "",
1555
+ ts__namespace.ScriptTarget.Latest,
1556
+ false,
1557
+ ts__namespace.ScriptKind.TS
1558
+ );
1559
+ if (statements.length > 0) {
1560
+ ts__namespace.addSyntheticLeadingComment(
1561
+ statements[0],
1562
+ ts__namespace.SyntaxKind.MultiLineCommentTrivia,
1563
+ " eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any ",
1564
+ true
1565
+ );
1566
+ ts__namespace.addSyntheticLeadingComment(
1567
+ statements[0],
1568
+ ts__namespace.SyntaxKind.MultiLineCommentTrivia,
1569
+ headerComment,
1570
+ true
1571
+ );
1572
+ }
1573
+ return this.factory.updateSourceFile(sourceFile, statements);
1574
+ }
1575
+ createImportStatement(imports, from) {
1576
+ if (imports.length === 1 && !from && imports[0].startsWith("@")) {
1577
+ return this.factory.createImportDeclaration(
1578
+ void 0,
1579
+ void 0,
1580
+ this.factory.createStringLiteral(imports[0]),
1581
+ void 0
1582
+ );
1583
+ }
1584
+ const fromModule = from || imports[0];
1585
+ const importNames = from ? imports : [];
1586
+ return this.factory.createImportDeclaration(
1587
+ void 0,
1588
+ importNames.length > 0 ? this.factory.createImportClause(
1589
+ false,
1590
+ void 0,
1591
+ this.factory.createNamedImports(
1592
+ importNames.map(
1593
+ (name) => this.factory.createImportSpecifier(
1594
+ false,
1595
+ void 0,
1596
+ this.factory.createIdentifier(name)
1597
+ )
1598
+ )
1599
+ )
1600
+ ) : void 0,
1601
+ this.factory.createStringLiteral(fromModule),
1602
+ void 0
1603
+ );
1604
+ }
1605
+ createTypeImportStatement(imports, from) {
1606
+ return this.factory.createImportDeclaration(
1607
+ void 0,
1608
+ this.factory.createImportClause(
1609
+ true,
1610
+ // typeOnly: true
1611
+ void 0,
1612
+ this.factory.createNamedImports(
1613
+ imports.map(
1614
+ (name) => this.factory.createImportSpecifier(
1615
+ false,
1616
+ void 0,
1617
+ this.factory.createIdentifier(name)
1618
+ )
1619
+ )
1620
+ )
1621
+ ),
1622
+ this.factory.createStringLiteral(from),
1623
+ void 0
1624
+ );
1625
+ }
1626
+ groupActionsByType(actions) {
1627
+ return actions.reduce(
1628
+ (acc, action) => {
1629
+ if (!acc[action.action_type]) {
1630
+ acc[action.action_type] = [];
1631
+ }
1632
+ acc[action.action_type].push(action);
1633
+ return acc;
1634
+ },
1635
+ {}
1636
+ );
1637
+ }
1638
+ createInputInterface(appName, action) {
1639
+ const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(
1640
+ this.sanitizeActionName(action.key)
1641
+ )}Inputs`;
1642
+ const properties = action.inputFields.map((field) => {
1643
+ const fieldType = this.mapFieldTypeToTypeNode(field);
1644
+ const isOptional = !field.required;
1645
+ let property = this.factory.createPropertySignature(
1646
+ void 0,
1647
+ this.sanitizeFieldName(field.key),
1648
+ isOptional ? this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken) : void 0,
1649
+ fieldType
1650
+ );
1651
+ if (field.helpText) {
1652
+ property = ts__namespace.addSyntheticLeadingComment(
1653
+ property,
1654
+ ts__namespace.SyntaxKind.MultiLineCommentTrivia,
1655
+ `* ${this.escapeComment(field.helpText)} `,
1656
+ true
1657
+ );
1658
+ }
1659
+ return property;
1660
+ });
1661
+ return this.factory.createInterfaceDeclaration(
1662
+ void 0,
1663
+ inputTypeName,
1664
+ void 0,
1665
+ void 0,
1666
+ properties
1667
+ );
1668
+ }
1669
+ createActionInterface(appName, actionType, typeActions) {
1670
+ const typeName = `${appName}${this.capitalize(actionType)}Actions`;
1671
+ const methods = typeActions.map((action) => {
1672
+ const actionName = this.sanitizeActionName(action.key);
1673
+ let methodSignature;
1674
+ if (action.inputFields.length > 0) {
1675
+ const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(
1676
+ this.sanitizeActionName(action.key)
1677
+ )}Inputs`;
1678
+ const inputsType = this.factory.createTypeLiteralNode([
1679
+ this.factory.createPropertySignature(
1680
+ void 0,
1681
+ "inputs",
1682
+ void 0,
1683
+ this.factory.createTypeReferenceNode(inputTypeName)
1684
+ )
1685
+ ]);
1686
+ const omitType = this.factory.createTypeReferenceNode("Omit", [
1687
+ this.factory.createTypeReferenceNode("ActionExecutionOptions"),
1688
+ this.factory.createLiteralTypeNode(
1689
+ this.factory.createStringLiteral("inputs")
1690
+ )
1691
+ ]);
1692
+ const optionsType = this.factory.createIntersectionTypeNode([
1693
+ inputsType,
1694
+ omitType
1695
+ ]);
1696
+ methodSignature = this.factory.createMethodSignature(
1697
+ void 0,
1698
+ actionName,
1699
+ void 0,
1700
+ void 0,
1701
+ [
1702
+ this.factory.createParameterDeclaration(
1703
+ void 0,
1704
+ void 0,
1705
+ "options",
1706
+ void 0,
1707
+ optionsType
1708
+ )
1709
+ ],
1710
+ this.factory.createTypeReferenceNode("Promise", [
1711
+ this.factory.createTypeReferenceNode("ActionExecutionResult")
1712
+ ])
1713
+ );
1714
+ } else {
1715
+ const genericInputsType = this.factory.createTypeLiteralNode([
1716
+ this.factory.createPropertySignature(
1717
+ void 0,
1718
+ "inputs",
1719
+ this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken),
1720
+ this.factory.createTypeReferenceNode("Record", [
1721
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword),
1722
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)
1723
+ ])
1724
+ )
1725
+ ]);
1726
+ const intersectionType = this.factory.createIntersectionTypeNode([
1727
+ genericInputsType,
1728
+ this.factory.createTypeReferenceNode("ActionExecutionOptions")
1729
+ ]);
1730
+ methodSignature = this.factory.createMethodSignature(
1731
+ void 0,
1732
+ actionName,
1733
+ void 0,
1734
+ void 0,
1735
+ [
1736
+ this.factory.createParameterDeclaration(
1737
+ void 0,
1738
+ void 0,
1739
+ "options",
1740
+ this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken),
1741
+ intersectionType
1742
+ )
1743
+ ],
1744
+ this.factory.createTypeReferenceNode("Promise", [
1745
+ this.factory.createTypeReferenceNode("ActionExecutionResult")
1746
+ ])
1747
+ );
1748
+ }
1749
+ if (action.description) {
1750
+ methodSignature = ts__namespace.addSyntheticLeadingComment(
1751
+ methodSignature,
1752
+ ts__namespace.SyntaxKind.MultiLineCommentTrivia,
1753
+ `* ${this.escapeComment(action.description)} `,
1754
+ true
1755
+ );
1756
+ }
1757
+ return methodSignature;
1758
+ });
1759
+ return this.factory.createInterfaceDeclaration(
1760
+ void 0,
1761
+ typeName,
1762
+ void 0,
1763
+ void 0,
1764
+ methods
1765
+ );
1766
+ }
1767
+ createAppProxyInterface(appName, actionsByType) {
1768
+ const properties = [
1769
+ ...Object.keys(actionsByType).map(
1770
+ (actionType) => this.factory.createPropertySignature(
1771
+ void 0,
1772
+ actionType,
1773
+ void 0,
1774
+ this.factory.createTypeReferenceNode(
1775
+ `${appName}${this.capitalize(actionType)}Actions`
1776
+ )
1777
+ )
1778
+ ),
1779
+ // Always include fetch method for authenticated HTTP requests
1780
+ this.createFetchMethodProperty()
1781
+ ];
1782
+ return this.factory.createInterfaceDeclaration(
1783
+ void 0,
1784
+ `${appName}AppProxy`,
1785
+ void 0,
1786
+ void 0,
1787
+ properties
1788
+ );
1789
+ }
1790
+ createFetchMethodProperty() {
1791
+ let property = this.factory.createPropertySignature(
1792
+ void 0,
1793
+ "fetch",
1794
+ void 0,
1795
+ this.factory.createFunctionTypeNode(
1796
+ void 0,
1797
+ [
1798
+ this.factory.createParameterDeclaration(
1799
+ void 0,
1800
+ void 0,
1801
+ "url",
1802
+ void 0,
1803
+ this.factory.createUnionTypeNode([
1804
+ this.factory.createTypeReferenceNode("string"),
1805
+ this.factory.createTypeReferenceNode("URL")
1806
+ ])
1807
+ ),
1808
+ this.factory.createParameterDeclaration(
1809
+ void 0,
1810
+ void 0,
1811
+ "init",
1812
+ this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken),
1813
+ this.factory.createTypeReferenceNode("ZapierFetchInitOptions")
1814
+ )
1815
+ ],
1816
+ this.factory.createTypeReferenceNode("Promise", [
1817
+ this.factory.createTypeReferenceNode("Response")
1818
+ ])
1819
+ )
1820
+ );
1821
+ property = ts__namespace.addSyntheticLeadingComment(
1822
+ property,
1823
+ ts__namespace.SyntaxKind.MultiLineCommentTrivia,
1824
+ "* Make authenticated HTTP requests through Zapier's Relay service ",
1825
+ true
1826
+ );
1827
+ return property;
1828
+ }
1829
+ createAppFactoryInterface(appName) {
1830
+ const callSignature = this.factory.createCallSignature(
1831
+ void 0,
1832
+ [
1833
+ this.factory.createParameterDeclaration(
1834
+ void 0,
1835
+ void 0,
1836
+ "options",
1837
+ void 0,
1838
+ this.factory.createTypeLiteralNode([
1839
+ this.factory.createPropertySignature(
1840
+ void 0,
1841
+ "authenticationId",
1842
+ void 0,
1843
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NumberKeyword)
1844
+ )
1845
+ ])
1846
+ )
1847
+ ],
1848
+ this.factory.createTypeReferenceNode(`${appName}AppProxy`)
1849
+ );
1850
+ return this.factory.createInterfaceDeclaration(
1851
+ void 0,
1852
+ `${appName}AppFactory`,
1853
+ void 0,
1854
+ void 0,
1855
+ [callSignature]
1856
+ );
1857
+ }
1858
+ createAppWithFactoryType(appName) {
1859
+ return this.factory.createTypeAliasDeclaration(
1860
+ void 0,
1861
+ `${appName}AppWithFactory`,
1862
+ void 0,
1863
+ this.factory.createIntersectionTypeNode([
1864
+ this.factory.createTypeReferenceNode(`${appName}AppFactory`),
1865
+ this.factory.createTypeReferenceNode(`${appName}AppProxy`)
1866
+ ])
1867
+ );
1868
+ }
1869
+ createModuleAugmentation(appKey, appName) {
1870
+ return this.factory.createModuleDeclaration(
1871
+ [this.factory.createToken(ts__namespace.SyntaxKind.DeclareKeyword)],
1872
+ this.factory.createStringLiteral("@zapier/zapier-sdk"),
1873
+ this.factory.createModuleBlock([
1874
+ this.factory.createInterfaceDeclaration(
1875
+ void 0,
1876
+ "ZapierSdkApps",
1877
+ void 0,
1878
+ void 0,
1879
+ [
1880
+ this.factory.createPropertySignature(
1881
+ void 0,
1882
+ appKey,
1883
+ void 0,
1884
+ this.factory.createTypeReferenceNode(`${appName}AppWithFactory`)
1885
+ )
1886
+ ]
1887
+ )
1888
+ ])
1889
+ );
1890
+ }
1891
+ mapFieldTypeToTypeNode(field) {
1892
+ if (field.choices && field.choices.length > 0) {
1893
+ const choiceValues = field.choices.filter(
1894
+ (choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
1895
+ ).map(
1896
+ (choice) => typeof choice.value === "string" ? this.factory.createLiteralTypeNode(
1897
+ this.factory.createStringLiteral(choice.value)
1898
+ ) : this.factory.createLiteralTypeNode(
1899
+ this.factory.createNumericLiteral(String(choice.value))
1900
+ )
1901
+ );
1902
+ if (choiceValues.length > 0) {
1903
+ return this.factory.createUnionTypeNode(choiceValues);
1904
+ }
1905
+ }
1906
+ switch (field.type?.toLowerCase()) {
1907
+ case "string":
1908
+ case "text":
1909
+ case "email":
1910
+ case "url":
1911
+ case "password":
1912
+ case "datetime":
1913
+ case "date":
1914
+ case "file":
1915
+ return this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword);
1916
+ case "integer":
1917
+ case "number":
1918
+ return this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NumberKeyword);
1919
+ case "boolean":
1920
+ return this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.BooleanKeyword);
1921
+ case "array":
1922
+ return this.factory.createArrayTypeNode(
1923
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)
1924
+ );
1925
+ case "object":
1926
+ return this.factory.createTypeReferenceNode("Record", [
1927
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword),
1928
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)
1929
+ ]);
1930
+ default:
1931
+ return this.factory.createUnionTypeNode([
1932
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword),
1933
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NumberKeyword),
1934
+ this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.BooleanKeyword)
1935
+ ]);
1936
+ }
1937
+ }
1938
+ generateEmptyTypesFile(appKey, version) {
1939
+ const appName = this.capitalize(appKey);
1940
+ const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1941
+ return `/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */
1942
+ /**
1943
+ * Auto-generated TypeScript types for Zapier ${appKey} actions
1944
+ ${versionComment}
1945
+ * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1946
+ *
1947
+ * No actions found for this app.
1948
+ */
1949
+
1950
+ import type { ActionExecutionOptions, ActionExecutionResult, ZapierFetchInitOptions } from '@zapier/zapier-sdk'
1951
+
1952
+ interface ${appName}AppProxy {
1953
+ /** Make authenticated HTTP requests through Zapier's Relay service */
1954
+ fetch: (url: string | URL, init?: ZapierFetchInitOptions) => Promise<Response>
1955
+ }
1956
+
1957
+ interface ${appName}AppFactory {
1958
+ (options: { authenticationId: number }): ${appName}AppProxy
1959
+ }
1960
+
1961
+ type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1962
+
1963
+ declare module "@zapier/zapier-sdk" {
1964
+ interface ZapierSdkApps {
1965
+ ${appKey}: ${appName}AppWithFactory
1966
+ }
1967
+ }
1968
+ `;
1969
+ }
1970
+ capitalize(str) {
1971
+ return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
1972
+ }
1973
+ sanitizeActionName(actionKey) {
1974
+ let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1975
+ if (/^[0-9]/.test(sanitized)) {
1976
+ sanitized = "_" + sanitized;
1977
+ }
1978
+ return sanitized;
1979
+ }
1980
+ sanitizeFieldName(fieldKey) {
1981
+ let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1982
+ if (/^[0-9]/.test(sanitized)) {
1983
+ sanitized = "_" + sanitized;
1984
+ }
1985
+ return sanitized;
1986
+ }
1987
+ escapeComment(comment) {
1988
+ return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
1989
+ }
1990
+ };
1991
+ async function detectTypesOutputDirectory() {
1992
+ const candidates = ["src", "lib"];
1993
+ for (const candidate of candidates) {
1994
+ try {
1995
+ await promises.access(candidate);
1996
+ return path.join(candidate, "zapier", "apps");
1997
+ } catch {
1998
+ }
1999
+ }
2000
+ return "./zapier/apps/";
2001
+ }
2002
+ var addPlugin = ({ sdk: sdk2, context }) => {
2003
+ const add = zapierSdk.createFunction(async function add2(options) {
2004
+ const {
2005
+ appKeys,
2006
+ authenticationIds,
2007
+ configPath,
2008
+ typesOutput = await detectTypesOutputDirectory()
2009
+ } = options;
2010
+ const resolvedTypesOutput = path.resolve(typesOutput);
2011
+ await promises.mkdir(resolvedTypesOutput, { recursive: true });
2012
+ console.log(`\u{1F4E6} Looking up ${appKeys.length} app(s)...`);
2013
+ const appsIterator = sdk2.listApps({ appKeys }).items();
2014
+ const apps = [];
2015
+ for await (const app of appsIterator) {
2016
+ apps.push(app);
2017
+ }
2018
+ if (apps.length === 0) {
2019
+ console.warn("\u26A0\uFE0F No apps found");
2020
+ return;
2021
+ }
2022
+ let authentications = [];
2023
+ if (authenticationIds && authenticationIds.length > 0) {
2024
+ console.log(
2025
+ `\u{1F510} Looking up ${authenticationIds.length} authentication(s)...`
2026
+ );
2027
+ const authsIterator = sdk2.listAuthentications({ authenticationIds }).items();
2028
+ for await (const auth of authsIterator) {
2029
+ authentications.push(auth);
2030
+ }
2031
+ console.log(`\u{1F510} Found ${authentications.length} authentication(s)`);
2032
+ }
2033
+ for (const app of apps) {
2034
+ console.log(`\u{1F4E6} Adding ${app.key}...`);
2035
+ try {
2036
+ const currentImplementationId = app.current_implementation_id;
2037
+ const [implementationName, version] = currentImplementationId.split("@");
2038
+ if (!implementationName || !version) {
2039
+ console.warn(
2040
+ `\u26A0\uFE0F Invalid implementation ID format for '${app.key}': ${currentImplementationId}. Expected format: <implementationName>@<version>. Skipping...`
2041
+ );
2042
+ continue;
2043
+ }
2044
+ const [manifestKey] = await context.updateManifestEntry(
2045
+ app.key,
2046
+ {
2047
+ implementationName,
2048
+ version
2049
+ },
2050
+ configPath
2051
+ );
2052
+ console.log(
2053
+ `\u{1F4DD} Locked ${app.key} to ${implementationName}@${version} using key '${manifestKey}'`
2054
+ );
2055
+ let authenticationId;
2056
+ if (authentications.length > 0) {
2057
+ const matchingAuth = authentications.find((auth) => {
2058
+ return auth.app_key === app.key;
2059
+ });
2060
+ if (matchingAuth) {
2061
+ authenticationId = matchingAuth.id;
2062
+ console.log(
2063
+ `\u{1F510} Using authentication ${authenticationId} (${matchingAuth.title}) for ${app.key}`
2064
+ );
2065
+ } else {
2066
+ console.warn(`\u26A0\uFE0F No matching authentication found for ${app.key}`);
2067
+ }
2068
+ }
2069
+ const typesPath = path.join(resolvedTypesOutput, `${manifestKey}.d.ts`);
2070
+ try {
2071
+ const generator = new AstTypeGenerator();
2072
+ const typeDefinitions = await generator.generateTypes({
2073
+ appKey: manifestKey,
2074
+ authenticationId,
2075
+ sdk: sdk2
2076
+ });
2077
+ await promises.writeFile(typesPath, typeDefinitions, "utf8");
2078
+ console.log(`\u{1F527} Generated types for ${manifestKey} at ${typesPath}`);
2079
+ } catch (error) {
2080
+ console.warn(`\u26A0\uFE0F Failed to generate types for ${app.key}: ${error}`);
2081
+ }
2082
+ } catch (error) {
2083
+ console.warn(`\u26A0\uFE0F Failed to process ${app.key}: ${error}`);
2084
+ }
2085
+ }
2086
+ console.log(`\u2705 Added ${apps.length} app(s) to manifest`);
2087
+ }, AddSchema);
2088
+ return {
2089
+ add,
1686
2090
  context: {
1687
2091
  meta: {
1688
- getConfigPath: {
2092
+ add: {
1689
2093
  categories: ["utility"],
1690
- inputSchema: GetConfigPathSchema
2094
+ inputSchema: AddSchema
1691
2095
  }
1692
2096
  }
1693
2097
  }
@@ -1699,9 +2103,9 @@ function createZapierCliSdk(options = {}) {
1699
2103
  let sdk2 = zapierSdk.createZapierSdkWithoutRegistry({
1700
2104
  debug: options.debug
1701
2105
  });
1702
- sdk2 = sdk2.addPlugin(generateTypesPlugin);
1703
2106
  sdk2 = sdk2.addPlugin(bundleCodePlugin);
1704
- sdk2 = sdk2.addPlugin(getConfigPathPlugin);
2107
+ sdk2 = sdk2.addPlugin(getLoginConfigPathPlugin);
2108
+ sdk2 = sdk2.addPlugin(addPlugin);
1705
2109
  sdk2 = sdk2.addPlugin(mcpPlugin);
1706
2110
  sdk2 = sdk2.addPlugin(loginPlugin);
1707
2111
  sdk2 = sdk2.addPlugin(logoutPlugin);
@@ -1711,7 +2115,7 @@ function createZapierCliSdk(options = {}) {
1711
2115
 
1712
2116
  // package.json
1713
2117
  var package_default = {
1714
- version: "0.8.3"};
2118
+ version: "0.9.0"};
1715
2119
 
1716
2120
  // src/cli.ts
1717
2121
  var program = new commander.Command();