@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.
Files changed (54) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +35 -51
  3. package/dist/cli.cjs +950 -433
  4. package/dist/cli.mjs +951 -434
  5. package/dist/index.cjs +729 -336
  6. package/dist/index.mjs +730 -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 +120 -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-utils.d.ts +2 -1
  22. package/dist/src/utils/cli-generator-utils.js +11 -5
  23. package/dist/src/utils/cli-generator.js +65 -65
  24. package/dist/src/utils/parameter-resolver.d.ts +4 -1
  25. package/dist/src/utils/parameter-resolver.js +92 -15
  26. package/dist/src/utils/schema-formatter.d.ts +5 -1
  27. package/dist/src/utils/schema-formatter.js +48 -18
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +4 -4
  30. package/src/plugins/add/ast-generator.ts +777 -0
  31. package/src/plugins/add/index.test.ts +58 -0
  32. package/src/plugins/add/index.ts +187 -0
  33. package/src/plugins/add/schemas.ts +26 -0
  34. package/src/plugins/getLoginConfigPath/index.ts +45 -0
  35. package/src/plugins/getLoginConfigPath/schemas.ts +10 -0
  36. package/src/plugins/index.ts +2 -2
  37. package/src/sdk.ts +4 -4
  38. package/src/utils/cli-generator-utils.ts +17 -5
  39. package/src/utils/cli-generator.ts +90 -79
  40. package/src/utils/parameter-resolver.ts +155 -21
  41. package/src/utils/schema-formatter.ts +68 -33
  42. package/tsup.config.ts +1 -1
  43. package/dist/src/plugins/generateTypes/index.d.ts +0 -21
  44. package/dist/src/plugins/generateTypes/index.js +0 -312
  45. package/dist/src/plugins/generateTypes/schemas.d.ts +0 -18
  46. package/dist/src/plugins/generateTypes/schemas.js +0 -14
  47. package/dist/src/plugins/getConfigPath/index.d.ts +0 -15
  48. package/dist/src/plugins/getConfigPath/index.js +0 -19
  49. package/dist/src/plugins/getConfigPath/schemas.d.ts +0 -3
  50. package/dist/src/plugins/getConfigPath/schemas.js +0 -5
  51. package/src/plugins/generateTypes/index.ts +0 -444
  52. package/src/plugins/generateTypes/schemas.ts +0 -23
  53. package/src/plugins/getConfigPath/index.ts +0 -42
  54. package/src/plugins/getConfigPath/schemas.ts +0 -8
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import { z } from 'zod';
4
- import { createFunction, OutputPropertySchema, AuthenticationIdPropertySchema, AppKeyPropertySchema, createZapierSdkWithoutRegistry, registryPlugin, ZapierError, formatErrorMessage, isPositional, hasResolver, getResolutionOrderForParams, getResolver } from '@zapier/zapier-sdk';
4
+ import { createFunction, OutputPropertySchema, DEFAULT_CONFIG_PATH, createZapierSdkWithoutRegistry, registryPlugin, ZapierError, formatErrorMessage, isPositional } from '@zapier/zapier-sdk';
5
5
  import inquirer from 'inquirer';
6
6
  import chalk3 from 'chalk';
7
7
  import util from 'util';
@@ -12,16 +12,52 @@ import pkceChallenge from 'pkce-challenge';
12
12
  import ora from 'ora';
13
13
  import { getLoggedInUser, logout, updateLogin, getConfigPath } from '@zapier/zapier-sdk-cli-login';
14
14
  import { startMcpServerAsProcess } from '@zapier/zapier-sdk-mcp';
15
+ import { buildSync } from 'esbuild';
15
16
  import * as fs from 'fs';
16
17
  import * as path from 'path';
17
- import { buildSync } from 'esbuild';
18
+ import { resolve, join } from 'path';
19
+ import * as ts from 'typescript';
20
+ import { mkdir, writeFile, access } from 'fs/promises';
18
21
 
22
+ function getLocalResolutionOrder(paramName, resolvers, resolved = /* @__PURE__ */ new Set()) {
23
+ const resolver = resolvers[paramName];
24
+ if (!resolver || resolver.type === "static") {
25
+ return [paramName];
26
+ }
27
+ const order = [];
28
+ if ("depends" in resolver && resolver.depends) {
29
+ for (const dependency of resolver.depends) {
30
+ if (!resolved.has(dependency)) {
31
+ order.push(...getLocalResolutionOrder(dependency, resolvers, resolved));
32
+ resolved.add(dependency);
33
+ }
34
+ }
35
+ }
36
+ if (!resolved.has(paramName)) {
37
+ order.push(paramName);
38
+ resolved.add(paramName);
39
+ }
40
+ return order;
41
+ }
42
+ function getLocalResolutionOrderForParams(paramNames, resolvers) {
43
+ const resolved = /* @__PURE__ */ new Set();
44
+ const order = [];
45
+ for (const paramName of paramNames) {
46
+ const paramOrder = getLocalResolutionOrder(paramName, resolvers, resolved);
47
+ for (const param of paramOrder) {
48
+ if (!order.includes(param)) {
49
+ order.push(param);
50
+ }
51
+ }
52
+ }
53
+ return order;
54
+ }
19
55
  var SchemaParameterResolver = class {
20
- async resolveParameters(schema, providedParams, sdk2) {
56
+ async resolveParameters(schema, providedParams, sdk2, functionName) {
21
57
  const parseResult = schema.safeParse(providedParams);
22
58
  const allParams = this.extractParametersFromSchema(schema);
23
59
  const resolvableParams = allParams.filter(
24
- (param) => hasResolver(param.name)
60
+ (param) => this.hasResolver(param.name, sdk2, functionName)
25
61
  );
26
62
  const missingResolvable = resolvableParams.filter((param) => {
27
63
  const hasValue = this.getNestedValue(providedParams, param.path) !== void 0;
@@ -57,11 +93,16 @@ var SchemaParameterResolver = class {
57
93
  const context = {
58
94
  sdk: sdk2,
59
95
  currentParams: providedParams,
60
- resolvedParams
96
+ resolvedParams,
97
+ functionName
61
98
  };
99
+ const localResolvers = this.getLocalResolvers(sdk2, functionName);
62
100
  if (functionallyRequired.length > 0) {
63
101
  const requiredParamNames = functionallyRequired.map((p) => p.name);
64
- const requiredResolutionOrder = getResolutionOrderForParams(requiredParamNames);
102
+ const requiredResolutionOrder = getLocalResolutionOrderForParams(
103
+ requiredParamNames,
104
+ localResolvers
105
+ );
65
106
  const orderedRequiredParams = requiredResolutionOrder.map((paramName) => {
66
107
  let param = functionallyRequired.find((p) => p.name === paramName);
67
108
  if (!param) {
@@ -74,7 +115,11 @@ var SchemaParameterResolver = class {
74
115
  }).filter((param) => param !== void 0);
75
116
  for (const param of orderedRequiredParams) {
76
117
  try {
77
- const value = await this.resolveParameter(param, context);
118
+ const value = await this.resolveParameter(
119
+ param,
120
+ context,
121
+ functionName
122
+ );
78
123
  this.setNestedValue(resolvedParams, param.path, value);
79
124
  context.resolvedParams = resolvedParams;
80
125
  } catch (error) {
@@ -101,11 +146,18 @@ var SchemaParameterResolver = class {
101
146
  }
102
147
  if (alwaysPrompt.length > 0) {
103
148
  const alwaysPromptNames = alwaysPrompt.map((p) => p.name);
104
- const alwaysPromptResolutionOrder = getResolutionOrderForParams(alwaysPromptNames);
149
+ const alwaysPromptResolutionOrder = getLocalResolutionOrderForParams(
150
+ alwaysPromptNames,
151
+ localResolvers
152
+ );
105
153
  const orderedAlwaysPromptParams = alwaysPromptResolutionOrder.map((paramName) => alwaysPrompt.find((p) => p.name === paramName)).filter((param) => param !== void 0);
106
154
  for (const param of orderedAlwaysPromptParams) {
107
155
  try {
108
- const value = await this.resolveParameter(param, context);
156
+ const value = await this.resolveParameter(
157
+ param,
158
+ context,
159
+ functionName
160
+ );
109
161
  this.setNestedValue(resolvedParams, param.path, value);
110
162
  context.resolvedParams = resolvedParams;
111
163
  } catch (error) {
@@ -129,11 +181,18 @@ var SchemaParameterResolver = class {
129
181
  ]);
130
182
  if (shouldResolveOptional.resolveOptional) {
131
183
  const optionalParamNames = trulyOptional.map((p) => p.name);
132
- const optionalResolutionOrder = getResolutionOrderForParams(optionalParamNames);
184
+ const optionalResolutionOrder = getLocalResolutionOrderForParams(
185
+ optionalParamNames,
186
+ localResolvers
187
+ );
133
188
  const orderedOptionalParams = optionalResolutionOrder.map((paramName) => trulyOptional.find((p) => p.name === paramName)).filter((param) => param !== void 0);
134
189
  for (const param of orderedOptionalParams) {
135
190
  try {
136
- const value = await this.resolveParameter(param, context);
191
+ const value = await this.resolveParameter(
192
+ param,
193
+ context,
194
+ functionName
195
+ );
137
196
  this.setNestedValue(resolvedParams, param.path, value);
138
197
  context.resolvedParams = resolvedParams;
139
198
  } catch (error) {
@@ -181,19 +240,19 @@ var SchemaParameterResolver = class {
181
240
  }
182
241
  return this.createResolvableParameter([fieldName], baseSchema, isRequired);
183
242
  }
184
- createResolvableParameter(path3, schema, isRequired) {
185
- if (path3.length === 0) return null;
186
- const name = path3[path3.length - 1];
243
+ createResolvableParameter(path2, schema, isRequired) {
244
+ if (path2.length === 0) return null;
245
+ const name = path2[path2.length - 1];
187
246
  return {
188
247
  name,
189
- path: path3,
248
+ path: path2,
190
249
  schema,
191
250
  description: schema.description,
192
251
  isRequired
193
252
  };
194
253
  }
195
- async resolveParameter(param, context) {
196
- const resolver = getResolver(param.name);
254
+ async resolveParameter(param, context, functionName) {
255
+ const resolver = this.getResolver(param.name, context.sdk, functionName);
197
256
  if (!resolver) {
198
257
  throw new Error(`No resolver found for parameter: ${param.name}`);
199
258
  }
@@ -278,10 +337,10 @@ var SchemaParameterResolver = class {
278
337
  break;
279
338
  }
280
339
  const newRequiredFields = newFields.filter(
281
- (field) => field.required
340
+ (field) => field.is_required
282
341
  );
283
342
  const newOptionalFields = newFields.filter(
284
- (field) => !field.required
343
+ (field) => !field.is_required
285
344
  );
286
345
  if (newRequiredFields.length > 0) {
287
346
  console.log(
@@ -346,15 +405,15 @@ Optional fields:`));
346
405
  }
347
406
  return inputs;
348
407
  }
349
- getNestedValue(obj, path3) {
350
- return path3.reduce(
408
+ getNestedValue(obj, path2) {
409
+ return path2.reduce(
351
410
  (current, key) => current?.[key],
352
411
  obj
353
412
  );
354
413
  }
355
- setNestedValue(obj, path3, value) {
356
- const lastKey = path3[path3.length - 1];
357
- const parent = path3.slice(0, -1).reduce((current, key) => {
414
+ setNestedValue(obj, path2, value) {
415
+ const lastKey = path2[path2.length - 1];
416
+ const parent = path2.slice(0, -1).reduce((current, key) => {
358
417
  const currentObj = current;
359
418
  if (!(key in currentObj)) {
360
419
  currentObj[key] = {};
@@ -368,7 +427,7 @@ Optional fields:`));
368
427
  const fieldPrompt = {
369
428
  type: fieldObj.type === "boolean" ? "confirm" : "input",
370
429
  name: fieldObj.key,
371
- message: `${fieldObj.label || fieldObj.key}${fieldObj.required ? " (required)" : " (optional)"}:`
430
+ message: `${fieldObj.label || fieldObj.key}${fieldObj.is_required ? " (required)" : " (optional)"}:`
372
431
  };
373
432
  if (fieldObj.helpText) {
374
433
  fieldPrompt.prefix = chalk3.gray(`\u2139 ${fieldObj.helpText}
@@ -393,7 +452,7 @@ Optional fields:`));
393
452
  const answer = await inquirer.prompt([fieldPrompt]);
394
453
  if (answer[fieldObj.key] !== void 0 && answer[fieldObj.key] !== "") {
395
454
  inputs[fieldObj.key] = answer[fieldObj.key];
396
- } else if (fieldObj.required) {
455
+ } else if (fieldObj.is_required) {
397
456
  throw new Error(`Required field ${fieldObj.key} cannot be empty`);
398
457
  }
399
458
  } catch (error) {
@@ -408,6 +467,40 @@ Optional fields:`));
408
467
  const errorObj = error;
409
468
  return errorObj?.name === "ExitPromptError" || errorObj?.message?.includes("User force closed") || errorObj?.isTTYError === true;
410
469
  }
470
+ hasResolver(paramName, sdk2, functionName) {
471
+ if (functionName && typeof sdk2.getRegistry === "function") {
472
+ const registry = sdk2.getRegistry();
473
+ const functionInfo = registry.functions.find(
474
+ (f) => f.name === functionName
475
+ );
476
+ if (functionInfo && functionInfo.resolvers?.[paramName]) {
477
+ return true;
478
+ }
479
+ }
480
+ return false;
481
+ }
482
+ getResolver(paramName, sdk2, functionName) {
483
+ if (functionName && typeof sdk2.getRegistry === "function") {
484
+ const registry = sdk2.getRegistry();
485
+ const functionInfo = registry.functions.find(
486
+ (f) => f.name === functionName
487
+ );
488
+ if (functionInfo && functionInfo.resolvers?.[paramName]) {
489
+ return functionInfo.resolvers[paramName];
490
+ }
491
+ }
492
+ return null;
493
+ }
494
+ getLocalResolvers(sdk2, functionName) {
495
+ if (!functionName || typeof sdk2.getRegistry !== "function") {
496
+ return {};
497
+ }
498
+ const registry = sdk2.getRegistry();
499
+ const functionInfo = registry.functions.find(
500
+ (f) => f.name === functionName
501
+ );
502
+ return functionInfo?.resolvers || {};
503
+ }
411
504
  };
412
505
  function getFormatMetadata(schema) {
413
506
  return schema?._def?.formatMeta;
@@ -415,8 +508,16 @@ function getFormatMetadata(schema) {
415
508
  function getOutputSchema(schema) {
416
509
  return schema?._def?.outputSchema;
417
510
  }
418
- function formatItemsFromSchema(inputSchema, items, startingNumber = 0) {
419
- const outputSchema = getOutputSchema(inputSchema);
511
+ function formatJsonOutput(data) {
512
+ if (data === void 0) {
513
+ return;
514
+ }
515
+ console.log(
516
+ util.inspect(data, { colors: true, depth: null, breakLength: 80 })
517
+ );
518
+ }
519
+ function formatItemsFromSchema(functionInfo, items, startingNumber = 0) {
520
+ const outputSchema = functionInfo.outputSchema || getOutputSchema(functionInfo.inputSchema);
420
521
  if (!outputSchema) {
421
522
  formatItemsGeneric(items, startingNumber);
422
523
  return;
@@ -427,16 +528,26 @@ function formatItemsFromSchema(inputSchema, items, startingNumber = 0) {
427
528
  return;
428
529
  }
429
530
  items.forEach((item, index) => {
430
- formatSingleItem(item, startingNumber + index, formatMeta);
531
+ const formatted = formatMeta.format(item);
532
+ formatSingleItem(formatted, startingNumber + index);
431
533
  });
432
534
  }
433
- function formatSingleItem(item, itemNumber, formatMeta) {
434
- const formatted = formatMeta.format(item);
535
+ function formatSingleItem(formatted, itemNumber) {
435
536
  let titleLine = `${chalk3.gray(`${itemNumber + 1}.`)} ${chalk3.cyan(formatted.title)}`;
436
- if (formatted.subtitle) {
437
- titleLine += ` ${chalk3.gray(formatted.subtitle)}`;
537
+ if (formatted.id) {
538
+ titleLine += ` ${chalk3.gray(`(ID: ${formatted.id})`)}`;
539
+ } else if (formatted.key) {
540
+ titleLine += ` ${chalk3.gray(`(${formatted.key})`)}`;
438
541
  }
439
542
  console.log(titleLine);
543
+ if (formatted.description) {
544
+ console.log(` ${chalk3.dim(formatted.description)}`);
545
+ }
546
+ if (formatted.data !== void 0) {
547
+ formatJsonOutput(formatted.data);
548
+ console.log();
549
+ return;
550
+ }
440
551
  for (const detail of formatted.details) {
441
552
  const styledText = applyStyle(detail.text, detail.style);
442
553
  console.log(` ${styledText}`);
@@ -458,40 +569,36 @@ function applyStyle(value, style) {
458
569
  return chalk3.blue(value);
459
570
  }
460
571
  }
572
+ function convertGenericItemToFormattedItem(item) {
573
+ const itemObj = item;
574
+ return {
575
+ title: itemObj.title || itemObj.name || itemObj.key || itemObj.id || "Item",
576
+ id: itemObj.id,
577
+ key: itemObj.key,
578
+ description: itemObj.description,
579
+ details: []
580
+ };
581
+ }
461
582
  function formatItemsGeneric(items, startingNumber = 0) {
462
583
  items.forEach((item, index) => {
463
- const itemObj = item;
464
- const name = itemObj.title || itemObj.name || itemObj.key || itemObj.id || "Item";
465
- console.log(
466
- `${chalk3.gray(`${startingNumber + index + 1}.`)} ${chalk3.cyan(name)}`
467
- );
468
- if (itemObj.description) {
469
- console.log(` ${chalk3.dim(itemObj.description)}`);
470
- }
471
- console.log();
584
+ const formatted = convertGenericItemToFormattedItem(item);
585
+ formatSingleItem(formatted, startingNumber + index);
472
586
  });
473
587
  }
474
- function formatJsonOutput(data) {
475
- if (data === void 0) {
476
- return;
477
- }
478
- if (data && typeof data === "object" && !Array.isArray(data) && (data.success !== void 0 || data.id || data.status)) {
479
- console.log(chalk3.green("\u2705 Action completed successfully!\n"));
480
- }
481
- console.log(
482
- util.inspect(data, { colors: true, depth: null, breakLength: 80 })
483
- );
484
- }
485
- function analyzeZodSchema(schema) {
588
+ function analyzeZodSchema(schema, functionInfo) {
486
589
  const parameters = [];
487
590
  if (schema._def && schema._def.typeName === "ZodEffects") {
488
591
  const innerSchema = schema._def.schema;
489
- return analyzeZodSchema(innerSchema);
592
+ return analyzeZodSchema(innerSchema, functionInfo);
490
593
  }
491
594
  if (schema instanceof z.ZodObject) {
492
595
  const shape = schema.shape;
493
596
  for (const [key, fieldSchema] of Object.entries(shape)) {
494
- const param = analyzeZodField(key, fieldSchema);
597
+ const param = analyzeZodField(
598
+ key,
599
+ fieldSchema,
600
+ functionInfo
601
+ );
495
602
  if (param) {
496
603
  parameters.push(param);
497
604
  }
@@ -499,7 +606,7 @@ function analyzeZodSchema(schema) {
499
606
  }
500
607
  return parameters;
501
608
  }
502
- function analyzeZodField(name, schema) {
609
+ function analyzeZodField(name, schema, functionInfo) {
503
610
  let baseSchema = schema;
504
611
  let required = true;
505
612
  let defaultValue = void 0;
@@ -533,6 +640,10 @@ function analyzeZodField(name, schema) {
533
640
  } else if (baseSchema instanceof z.ZodRecord) {
534
641
  paramType = "string";
535
642
  }
643
+ let paramHasResolver = false;
644
+ if (functionInfo?.resolvers?.[name]) {
645
+ paramHasResolver = true;
646
+ }
536
647
  return {
537
648
  name,
538
649
  type: paramType,
@@ -540,7 +651,7 @@ function analyzeZodField(name, schema) {
540
651
  description: schema.description,
541
652
  default: defaultValue,
542
653
  choices,
543
- hasResolver: hasResolver(name),
654
+ hasResolver: paramHasResolver,
544
655
  isPositional: isPositional(schema)
545
656
  };
546
657
  }
@@ -562,12 +673,7 @@ function generateCliCommands(program2, sdk2) {
562
673
  return;
563
674
  }
564
675
  const cliCommandName = methodNameToCliCommand(fnInfo.name);
565
- const config = createCommandConfig(
566
- cliCommandName,
567
- fnInfo.name,
568
- fnInfo.inputSchema,
569
- sdk2
570
- );
676
+ const config = createCommandConfig(cliCommandName, fnInfo, sdk2);
571
677
  addCommand(program2, cliCommandName, config);
572
678
  });
573
679
  program2.configureHelp({
@@ -631,14 +737,15 @@ function generateCliCommands(program2, sdk2) {
631
737
  }
632
738
  });
633
739
  }
634
- function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
635
- const parameters = analyzeZodSchema(schema);
740
+ function createCommandConfig(cliCommandName, functionInfo, sdk2) {
741
+ const schema = functionInfo.inputSchema;
742
+ const parameters = analyzeZodSchema(schema, functionInfo);
636
743
  const description = schema.description || `${cliCommandName} command`;
637
744
  const handler = async (...args) => {
638
745
  try {
639
746
  const commandObj = args[args.length - 1];
640
747
  const options = commandObj.opts();
641
- const isListCommand = cliCommandName.startsWith("list-");
748
+ const isListCommand = functionInfo.type === "list";
642
749
  const hasPaginationParams = parameters.some(
643
750
  (p) => p.name === "maxItems" || p.name === "pageSize"
644
751
  );
@@ -653,21 +760,22 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
653
760
  const resolvedParams = await resolver.resolveParameters(
654
761
  schema,
655
762
  rawParams,
656
- sdk2
763
+ sdk2,
764
+ functionInfo.name
657
765
  );
658
766
  if (isListCommand && hasPaginationParams && !shouldUseJson && !hasUserSpecifiedMaxItems) {
659
767
  const sdkObj = sdk2;
660
- const sdkIterator = sdkObj[sdkMethodName](resolvedParams);
768
+ const sdkIterator = sdkObj[functionInfo.name](resolvedParams);
661
769
  await handlePaginatedListWithAsyncIteration(
662
- sdkMethodName,
770
+ functionInfo.name,
663
771
  sdkIterator,
664
- schema
772
+ functionInfo
665
773
  );
666
774
  } else {
667
775
  const hasOutputFile = resolvedParams.output;
668
776
  if (hasOutputFile) {
669
777
  const sdkObj2 = sdk2;
670
- await sdkObj2[sdkMethodName](resolvedParams);
778
+ await sdkObj2[functionInfo.name](resolvedParams);
671
779
  console.log(
672
780
  chalk3.green(`\u2705 ${cliCommandName} completed successfully!`)
673
781
  );
@@ -675,7 +783,7 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
675
783
  return;
676
784
  }
677
785
  const sdkObj = sdk2;
678
- const result = await sdkObj[sdkMethodName](resolvedParams);
786
+ const result = await sdkObj[functionInfo.name](resolvedParams);
679
787
  const items = result?.data ? result.data : result;
680
788
  if (shouldUseJson) {
681
789
  console.log(JSON.stringify(items, null, 2));
@@ -685,8 +793,7 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
685
793
  resolvedParams.maxItems,
686
794
  hasUserSpecifiedMaxItems,
687
795
  shouldUseJson,
688
- schema,
689
- sdkMethodName
796
+ functionInfo
690
797
  );
691
798
  } else {
692
799
  formatJsonOutput(items);
@@ -730,6 +837,7 @@ function createCommandConfig(cliCommandName, sdkMethodName, schema, sdk2) {
730
837
  }
731
838
  function addCommand(program2, commandName, config) {
732
839
  const command = program2.command(commandName).description(config.description);
840
+ let hasPositionalArray = false;
733
841
  config.parameters.forEach((param) => {
734
842
  const kebabName = param.name.replace(/([A-Z])/g, "-$1").toLowerCase();
735
843
  if (param.hasResolver && param.required) {
@@ -737,6 +845,19 @@ function addCommand(program2, commandName, config) {
737
845
  `[${kebabName}]`,
738
846
  param.description || `${kebabName} parameter`
739
847
  );
848
+ } else if (param.required && param.type === "array" && !hasPositionalArray) {
849
+ hasPositionalArray = true;
850
+ command.argument(
851
+ `<${kebabName}...>`,
852
+ param.description || `${kebabName} parameter`
853
+ );
854
+ } else if (param.required && param.type === "array") {
855
+ const flags = [`--${kebabName}`];
856
+ const flagSignature = flags.join(", ") + ` <values...>`;
857
+ command.requiredOption(
858
+ flagSignature,
859
+ param.description || `${kebabName} parameter (required)`
860
+ );
740
861
  } else if (param.required) {
741
862
  command.argument(
742
863
  `<${kebabName}>`,
@@ -793,6 +914,9 @@ function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
793
914
  return sdkParams;
794
915
  }
795
916
  function convertValue(value, type) {
917
+ if (value === void 0) {
918
+ return void 0;
919
+ }
796
920
  switch (type) {
797
921
  case "number":
798
922
  return Number(value);
@@ -812,12 +936,14 @@ function convertValue(value, type) {
812
936
  return value;
813
937
  }
814
938
  }
815
- async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, schema) {
816
- const itemName = getItemNameFromMethod(sdkMethodName);
939
+ async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, functionInfo) {
940
+ const itemName = getItemNameFromMethod(functionInfo);
817
941
  let totalShown = 0;
818
942
  let pageCount = 0;
819
- console.log(chalk3.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName)}
820
- `));
943
+ console.log(
944
+ chalk3.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName, functionInfo)}
945
+ `)
946
+ );
821
947
  try {
822
948
  for await (const page of sdkResult) {
823
949
  const items = page.data || page;
@@ -836,12 +962,14 @@ async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, s
836
962
  if (pageCount > 1) {
837
963
  console.clear();
838
964
  console.log(
839
- chalk3.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName)}
840
- `)
965
+ chalk3.blue(
966
+ `\u{1F4CB} ${getListTitleFromMethod(sdkMethodName, functionInfo)}
967
+ `
968
+ )
841
969
  );
842
970
  }
843
- if (schema) {
844
- formatItemsFromSchema(schema, items, totalShown);
971
+ if (functionInfo) {
972
+ formatItemsFromSchema(functionInfo, items, totalShown);
845
973
  } else {
846
974
  formatItemsGeneric2(items, totalShown);
847
975
  }
@@ -877,8 +1005,8 @@ async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, s
877
1005
  console.log(chalk3.yellow(`No ${itemName} found.`));
878
1006
  return;
879
1007
  }
880
- if (schema) {
881
- formatItemsFromSchema(schema, items, 0);
1008
+ if (functionInfo) {
1009
+ formatItemsFromSchema(functionInfo, items, 0);
882
1010
  } else {
883
1011
  formatItemsGeneric2(items, 0);
884
1012
  }
@@ -889,7 +1017,7 @@ async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, s
889
1017
  }
890
1018
  }
891
1019
  }
892
- function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxItems, useRawJson, schema, methodName) {
1020
+ function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxItems, useRawJson, functionInfo) {
893
1021
  if (!Array.isArray(result)) {
894
1022
  if (useRawJson) {
895
1023
  console.log(JSON.stringify(result, null, 2));
@@ -902,7 +1030,7 @@ function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxIt
902
1030
  console.log(JSON.stringify(result, null, 2));
903
1031
  return;
904
1032
  }
905
- const itemName = methodName ? getItemNameFromMethod(methodName) : "items";
1033
+ const itemName = functionInfo ? getItemNameFromMethod(functionInfo) : "items";
906
1034
  if (result.length === 0) {
907
1035
  console.log(chalk3.yellow(`No ${itemName} found.`));
908
1036
  return;
@@ -910,8 +1038,8 @@ function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxIt
910
1038
  console.log(chalk3.green(`
911
1039
  \u2705 Found ${result.length} ${itemName}:
912
1040
  `));
913
- if (schema) {
914
- formatItemsFromSchema(schema, result);
1041
+ if (functionInfo) {
1042
+ formatItemsFromSchema(functionInfo, result);
915
1043
  } else {
916
1044
  formatItemsGeneric2(result);
917
1045
  }
@@ -940,18 +1068,17 @@ function formatItemsGeneric2(items, startingNumber = 0) {
940
1068
  console.log();
941
1069
  });
942
1070
  }
943
- function getItemNameFromMethod(methodName) {
944
- const listMatch = methodName.match(/^list(.+)$/);
945
- if (listMatch) {
946
- return listMatch[1].toLowerCase();
1071
+ function getItemNameFromMethod(functionInfo) {
1072
+ if (functionInfo.itemType) {
1073
+ return `${functionInfo.itemType} items`;
947
1074
  }
948
1075
  return "items";
949
1076
  }
950
- function getListTitleFromMethod(methodName) {
951
- const itemName = getItemNameFromMethod(methodName);
952
- if (itemName === "items") return "Available Items";
953
- const capitalized = itemName.charAt(0).toUpperCase() + itemName.slice(1);
954
- return `Available ${capitalized}`;
1077
+ function getListTitleFromMethod(methodName, functionInfo) {
1078
+ if (functionInfo.itemType) {
1079
+ return `Available ${functionInfo.itemType} items`;
1080
+ }
1081
+ return `${methodName} items`;
955
1082
  }
956
1083
 
957
1084
  // src/utils/constants.ts
@@ -1018,28 +1145,28 @@ var client_default = api;
1018
1145
 
1019
1146
  // src/utils/getCallablePromise.ts
1020
1147
  var getCallablePromise = () => {
1021
- let resolve2 = () => {
1148
+ let resolve3 = () => {
1022
1149
  };
1023
1150
  let reject = () => {
1024
1151
  };
1025
1152
  const promise = new Promise((_resolve, _reject) => {
1026
- resolve2 = _resolve;
1153
+ resolve3 = _resolve;
1027
1154
  reject = _reject;
1028
1155
  });
1029
1156
  return {
1030
1157
  promise,
1031
- resolve: resolve2,
1158
+ resolve: resolve3,
1032
1159
  reject
1033
1160
  };
1034
1161
  };
1035
1162
  var getCallablePromise_default = getCallablePromise;
1036
1163
  var findAvailablePort = () => {
1037
- return new Promise((resolve2, reject) => {
1164
+ return new Promise((resolve3, reject) => {
1038
1165
  let portIndex = 0;
1039
1166
  const tryPort = (port) => {
1040
1167
  const server = express().listen(port, () => {
1041
1168
  server.close();
1042
- resolve2(port);
1169
+ resolve3(port);
1043
1170
  });
1044
1171
  server.on("error", (err) => {
1045
1172
  if (err.code === "EADDRINUSE") {
@@ -1129,15 +1256,15 @@ var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
1129
1256
  } finally {
1130
1257
  process.off("SIGINT", cleanup);
1131
1258
  process.off("SIGTERM", cleanup);
1132
- await new Promise((resolve2) => {
1259
+ await new Promise((resolve3) => {
1133
1260
  const timeout = setTimeout(() => {
1134
1261
  log_default.info("Server close timed out, forcing connection shutdown...");
1135
1262
  connections.forEach((conn) => conn.destroy());
1136
- resolve2();
1263
+ resolve3();
1137
1264
  }, 1e3);
1138
1265
  server.close(() => {
1139
1266
  clearTimeout(timeout);
1140
- resolve2();
1267
+ resolve3();
1141
1268
  });
1142
1269
  });
1143
1270
  }
@@ -1232,323 +1359,6 @@ var mcpPlugin = ({ context }) => {
1232
1359
  }
1233
1360
  };
1234
1361
  };
1235
- var GenerateTypesSchema = z.object({
1236
- appKey: AppKeyPropertySchema.describe("App key to generate SDK code for"),
1237
- authenticationId: AuthenticationIdPropertySchema.optional(),
1238
- output: OutputPropertySchema.optional().describe(
1239
- "Output file path (defaults to generated/<appKey>.ts)"
1240
- ),
1241
- lockFilePath: z.string().optional().describe("Path to the .zapierrc lock file (defaults to .zapierrc)")
1242
- }).describe("Generate TypeScript SDK code for a specific app");
1243
- var generateTypesPlugin = ({ sdk: sdk2 }) => {
1244
- const generateTypesWithSdk = createFunction(
1245
- async function generateTypesWithSdk2(options) {
1246
- return await generateTypes({ ...options, sdk: sdk2 });
1247
- },
1248
- GenerateTypesSchema
1249
- );
1250
- return {
1251
- generateTypes: generateTypesWithSdk,
1252
- context: {
1253
- meta: {
1254
- generateTypes: {
1255
- categories: ["utility"],
1256
- inputSchema: GenerateTypesSchema
1257
- }
1258
- }
1259
- }
1260
- };
1261
- };
1262
- function generateFetchMethodSignature() {
1263
- return ` /** Make authenticated HTTP requests through Zapier's Relay service */
1264
- fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
1265
- }
1266
- async function generateTypes(options) {
1267
- const {
1268
- appKey,
1269
- authenticationId,
1270
- output = `./types/${appKey}.d.ts`,
1271
- sdk: sdk2
1272
- } = options;
1273
- const { app, version } = parseAppIdentifier(appKey);
1274
- const actionsResult = await sdk2.listActions({
1275
- appKey: app
1276
- });
1277
- const actions = actionsResult.data;
1278
- if (actions.length === 0) {
1279
- const typeDefinitions2 = generateEmptyTypesFile(app, version);
1280
- if (output) {
1281
- fs.mkdirSync(path.dirname(output), { recursive: true });
1282
- fs.writeFileSync(output, typeDefinitions2, "utf8");
1283
- }
1284
- return typeDefinitions2;
1285
- }
1286
- const actionsWithFields = [];
1287
- if (authenticationId) {
1288
- for (const action of actions) {
1289
- try {
1290
- const manifestEntry = sdk2.getContext().getManifestEntry(appKey);
1291
- const fieldsResult = await sdk2.listInputFields({
1292
- // 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
1293
- appKey: manifestEntry ? appKey : action.app_key,
1294
- actionKey: action.key,
1295
- actionType: action.action_type,
1296
- authenticationId
1297
- });
1298
- const fields = fieldsResult.data.map((field) => {
1299
- const fieldObj = field;
1300
- return {
1301
- ...fieldObj,
1302
- required: fieldObj.is_required || fieldObj.required || false
1303
- };
1304
- });
1305
- actionsWithFields.push({
1306
- ...action,
1307
- inputFields: fields,
1308
- name: action.title || action.key
1309
- });
1310
- } catch {
1311
- actionsWithFields.push({
1312
- ...action,
1313
- inputFields: [],
1314
- name: action.title || action.key
1315
- });
1316
- }
1317
- }
1318
- } else {
1319
- actions.forEach((action) => {
1320
- actionsWithFields.push({
1321
- ...action,
1322
- inputFields: [],
1323
- name: action.title || action.key
1324
- });
1325
- });
1326
- }
1327
- const typeDefinitions = generateTypeDefinitions(
1328
- app,
1329
- actionsWithFields,
1330
- version
1331
- );
1332
- if (output) {
1333
- fs.mkdirSync(path.dirname(output), { recursive: true });
1334
- fs.writeFileSync(output, typeDefinitions, "utf8");
1335
- }
1336
- return typeDefinitions;
1337
- }
1338
- function parseAppIdentifier(identifier) {
1339
- const parts = identifier.split("@");
1340
- return {
1341
- app: parts[0],
1342
- version: parts[1]
1343
- };
1344
- }
1345
- function generateTypeDefinitions(appKey, actions, version) {
1346
- if (actions.length === 0) {
1347
- return generateEmptyTypesFile(appKey, version);
1348
- }
1349
- const actionsByType = actions.reduce(
1350
- (acc, action) => {
1351
- if (!acc[action.action_type]) {
1352
- acc[action.action_type] = [];
1353
- }
1354
- acc[action.action_type].push(action);
1355
- return acc;
1356
- },
1357
- {}
1358
- );
1359
- const appName = capitalize(appKey);
1360
- const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1361
- let output = `/* eslint-disable @typescript-eslint/naming-convention */
1362
- /**
1363
- * Auto-generated TypeScript types for Zapier ${appKey} actions
1364
- ${versionComment}
1365
- * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1366
- *
1367
- * Usage:
1368
- * import type { ${appName}Sdk } from './path/to/this/file'
1369
- * const sdk = createZapierSdk() as unknown as ${appName}Sdk
1370
- *
1371
- * // Direct usage (per-call auth):
1372
- * await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
1373
- *
1374
- * // Factory usage (pinned auth):
1375
- * const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
1376
- * await my${appName}.search.user_by_email({ inputs: { email } })
1377
- */
1378
-
1379
- import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
1380
- import { z } from 'zod'
1381
- import { RelayFetchSchema } from '@zapier/zapier-sdk'
1382
-
1383
- `;
1384
- actions.forEach((action) => {
1385
- if (action.inputFields.length > 0) {
1386
- const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
1387
- sanitizeActionName(action.key)
1388
- )}Inputs`;
1389
- output += `interface ${inputTypeName} {
1390
- `;
1391
- action.inputFields.forEach((field) => {
1392
- const isOptional = !field.required;
1393
- const fieldType = mapFieldTypeToTypeScript(field);
1394
- const description = field.helpText ? ` /** ${escapeComment(field.helpText)} */
1395
- ` : "";
1396
- output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}
1397
- `;
1398
- });
1399
- output += `}
1400
-
1401
- `;
1402
- }
1403
- });
1404
- Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
1405
- const typeName = `${appName}${capitalize(actionType)}Actions`;
1406
- output += `interface ${typeName} {
1407
- `;
1408
- typeActions.forEach((action) => {
1409
- const actionName = sanitizeActionName(action.key);
1410
- const description = action.description ? ` /** ${escapeComment(action.description)} */
1411
- ` : "";
1412
- if (action.inputFields.length > 0) {
1413
- const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
1414
- sanitizeActionName(action.key)
1415
- )}Inputs`;
1416
- output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>
1417
- `;
1418
- } else {
1419
- output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>
1420
- `;
1421
- }
1422
- });
1423
- output += `}
1424
-
1425
- `;
1426
- });
1427
- output += `interface ${appName}AppProxy {
1428
- `;
1429
- Object.keys(actionsByType).forEach((actionType) => {
1430
- const typeName = `${appName}${capitalize(actionType)}Actions`;
1431
- output += ` ${actionType}: ${typeName}
1432
- `;
1433
- });
1434
- output += generateFetchMethodSignature() + "\n";
1435
- output += `}
1436
-
1437
- `;
1438
- output += `interface ${appName}AppFactory {
1439
- `;
1440
- output += ` (options: { authenticationId: number }): ${appName}AppProxy
1441
- `;
1442
- output += `}
1443
-
1444
- `;
1445
- output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1446
-
1447
- `;
1448
- output += `export interface ${appName}Sdk {
1449
- `;
1450
- output += ` apps: {
1451
- `;
1452
- output += ` ${appKey}: ${appName}AppWithFactory
1453
- `;
1454
- output += ` }
1455
- `;
1456
- output += `}
1457
- `;
1458
- return output;
1459
- }
1460
- function generateEmptyTypesFile(appKey, version) {
1461
- const appName = capitalize(appKey);
1462
- const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1463
- return `/* eslint-disable @typescript-eslint/naming-convention */
1464
- /**
1465
- * Auto-generated TypeScript types for Zapier ${appKey} actions
1466
- ${versionComment}
1467
- * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1468
- *
1469
- * No actions found for this app.
1470
- */
1471
-
1472
- import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
1473
- import { z } from 'zod'
1474
- import { RelayFetchSchema } from '@zapier/zapier-sdk'
1475
-
1476
- interface ${appName}AppProxy {
1477
- // No actions available
1478
- ${generateFetchMethodSignature()}
1479
- }
1480
-
1481
- interface ${appName}AppFactory {
1482
- (options: { authenticationId: number }): ${appName}AppProxy
1483
- }
1484
-
1485
- type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
1486
-
1487
- export interface ${appName}Sdk {
1488
- apps: {
1489
- ${appKey}: ${appName}AppWithFactory
1490
- }
1491
- }
1492
- `;
1493
- }
1494
- function capitalize(str) {
1495
- return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
1496
- }
1497
- function sanitizeActionName(actionKey) {
1498
- let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1499
- if (/^[0-9]/.test(sanitized)) {
1500
- sanitized = "_" + sanitized;
1501
- }
1502
- return sanitized;
1503
- }
1504
- function sanitizeFieldName(fieldKey) {
1505
- let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
1506
- if (/^[0-9]/.test(sanitized)) {
1507
- sanitized = "_" + sanitized;
1508
- }
1509
- return sanitized;
1510
- }
1511
- function escapeComment(comment) {
1512
- return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
1513
- }
1514
- function mapFieldTypeToTypeScript(field) {
1515
- if (field.choices && field.choices.length > 0) {
1516
- const choiceValues = field.choices.filter(
1517
- (choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
1518
- ).map(
1519
- (choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value
1520
- );
1521
- if (choiceValues.length > 0) {
1522
- return choiceValues.join(" | ");
1523
- }
1524
- }
1525
- switch (field.type?.toLowerCase()) {
1526
- case "string":
1527
- case "text":
1528
- case "email":
1529
- case "url":
1530
- case "password":
1531
- return "string";
1532
- case "integer":
1533
- case "number":
1534
- return "number";
1535
- case "boolean":
1536
- return "boolean";
1537
- case "datetime":
1538
- case "date":
1539
- return "string";
1540
- // ISO date strings
1541
- case "file":
1542
- return "string";
1543
- // File URL or content
1544
- case "array":
1545
- return "any[]";
1546
- case "object":
1547
- return "Record<string, any>";
1548
- default:
1549
- return "string | number | boolean";
1550
- }
1551
- }
1552
1362
  var BundleCodeSchema = z.object({
1553
1363
  input: z.string().min(1).describe("Input TypeScript file path to bundle"),
1554
1364
  output: OutputPropertySchema.optional().describe(
@@ -1640,21 +1450,728 @@ async function bundleCode(options) {
1640
1450
  );
1641
1451
  }
1642
1452
  }
1643
- var GetConfigPathSchema = z.object({}).describe("Show the path to the configuration file");
1644
- var getConfigPathPlugin = () => {
1645
- const getConfigPathWithSdk = createFunction(
1646
- async function getConfigPathWithSdk2(_options) {
1453
+ var GetLoginConfigPathSchema = z.object({}).describe("Show the path to the login configuration file");
1454
+ var getLoginConfigPathPlugin = () => {
1455
+ const getLoginConfigPathWithSdk = createFunction(
1456
+ async function getLoginConfigPathWithSdk2(_options) {
1647
1457
  return getConfigPath();
1648
1458
  },
1649
- GetConfigPathSchema
1459
+ GetLoginConfigPathSchema
1650
1460
  );
1651
1461
  return {
1652
- getConfigPath: getConfigPathWithSdk,
1462
+ getLoginConfigPath: getLoginConfigPathWithSdk,
1463
+ context: {
1464
+ meta: {
1465
+ getLoginConfigPath: {
1466
+ categories: ["utility"],
1467
+ inputSchema: GetLoginConfigPathSchema
1468
+ }
1469
+ }
1470
+ }
1471
+ };
1472
+ };
1473
+ var AddSchema = z.object({
1474
+ appKeys: z.array(z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required"),
1475
+ authenticationIds: z.array(z.string()).optional().describe("Authentication IDs to use for type generation"),
1476
+ configPath: z.string().optional().describe(
1477
+ `Path to Zapier config file (defaults to '${DEFAULT_CONFIG_PATH}')`
1478
+ ),
1479
+ typesOutput: z.string().optional().describe(
1480
+ "Directory for TypeScript type files (defaults to (src|lib|.)/zapier/apps/)"
1481
+ )
1482
+ });
1483
+ var AstTypeGenerator = class {
1484
+ constructor() {
1485
+ this.factory = ts.factory;
1486
+ this.printer = ts.createPrinter({
1487
+ newLine: ts.NewLineKind.LineFeed,
1488
+ removeComments: false,
1489
+ omitTrailingSemicolon: false
1490
+ });
1491
+ }
1492
+ /**
1493
+ * Generate TypeScript types using AST for a specific app
1494
+ */
1495
+ async generateTypes(options) {
1496
+ const { appKey, authenticationId, sdk: sdk2 } = options;
1497
+ const { app, version } = this.parseAppIdentifier(appKey);
1498
+ const actionsResult = await sdk2.listActions({
1499
+ appKey: app
1500
+ });
1501
+ const actions = actionsResult.data;
1502
+ if (actions.length === 0) {
1503
+ return this.generateEmptyTypesFile(app, version);
1504
+ }
1505
+ const actionsWithFields = [];
1506
+ if (authenticationId) {
1507
+ for (const action of actions) {
1508
+ try {
1509
+ const fieldsResult = await sdk2.listInputFields({
1510
+ appKey,
1511
+ actionKey: action.key,
1512
+ actionType: action.action_type,
1513
+ authenticationId
1514
+ });
1515
+ const fields = fieldsResult.data.map(
1516
+ (field) => {
1517
+ const fieldObj = field;
1518
+ return {
1519
+ ...fieldObj,
1520
+ required: fieldObj.is_required || fieldObj.required || false
1521
+ };
1522
+ }
1523
+ );
1524
+ actionsWithFields.push({
1525
+ ...action,
1526
+ inputFields: fields,
1527
+ name: action.title || action.key
1528
+ });
1529
+ } catch {
1530
+ actionsWithFields.push({
1531
+ ...action,
1532
+ inputFields: [],
1533
+ name: action.title || action.key
1534
+ });
1535
+ }
1536
+ }
1537
+ } else {
1538
+ actions.forEach(
1539
+ (action) => {
1540
+ actionsWithFields.push({
1541
+ ...action,
1542
+ inputFields: [],
1543
+ name: action.title || action.key,
1544
+ app_key: action.app_key || appKey,
1545
+ action_type: action.action_type || "write",
1546
+ title: action.title || action.key,
1547
+ type: "action",
1548
+ description: action.description || ""
1549
+ });
1550
+ }
1551
+ );
1552
+ }
1553
+ const sourceFile = this.createSourceFile(app, actionsWithFields, version);
1554
+ return this.printer.printFile(sourceFile);
1555
+ }
1556
+ parseAppIdentifier(identifier) {
1557
+ const parts = identifier.split("@");
1558
+ return {
1559
+ app: parts[0],
1560
+ version: parts[1]
1561
+ };
1562
+ }
1563
+ createSourceFile(appKey, actions, version) {
1564
+ const appName = this.capitalize(appKey);
1565
+ const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
1566
+ const headerComment = `Auto-generated TypeScript types for Zapier ${appKey} actions
1567
+ ${versionComment.slice(3)}
1568
+ Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
1569
+
1570
+ This file automatically augments the base SDK types when present.
1571
+ No manual imports or type casting required.
1572
+
1573
+ Usage:
1574
+ import { createZapierSdk } from "@zapier/zapier-sdk";
1575
+
1576
+ const zapier = createZapierSdk();
1577
+ // Types are automatically available:
1578
+ await zapier.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
1579
+
1580
+ // Factory usage (pinned auth):
1581
+ const my${appName} = zapier.apps.${appKey}({ authenticationId: 123 })
1582
+ await my${appName}.search.user_by_email({ inputs: { email } })`;
1583
+ const statements = [
1584
+ // Import the SDK to activate module augmentation
1585
+ this.createImportStatement(["@zapier/zapier-sdk"]),
1586
+ // Import types we'll use
1587
+ this.createTypeImportStatement(
1588
+ [
1589
+ "ActionExecutionOptions",
1590
+ "ActionExecutionResult",
1591
+ "ZapierFetchInitOptions"
1592
+ ],
1593
+ "@zapier/zapier-sdk"
1594
+ )
1595
+ ];
1596
+ const actionsByType = this.groupActionsByType(actions);
1597
+ actions.forEach((action) => {
1598
+ if (action.inputFields.length > 0) {
1599
+ const inputInterface = this.createInputInterface(appName, action);
1600
+ statements.push(inputInterface);
1601
+ }
1602
+ });
1603
+ Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
1604
+ const actionInterface = this.createActionInterface(
1605
+ appName,
1606
+ actionType,
1607
+ typeActions
1608
+ );
1609
+ statements.push(actionInterface);
1610
+ });
1611
+ const appProxyInterface = this.createAppProxyInterface(
1612
+ appName,
1613
+ actionsByType
1614
+ );
1615
+ statements.push(appProxyInterface);
1616
+ const appFactoryInterface = this.createAppFactoryInterface(appName);
1617
+ statements.push(appFactoryInterface);
1618
+ const appWithFactoryType = this.createAppWithFactoryType(appName);
1619
+ statements.push(appWithFactoryType);
1620
+ const moduleAugmentation = this.createModuleAugmentation(appKey, appName);
1621
+ statements.push(moduleAugmentation);
1622
+ statements.push(
1623
+ this.factory.createExportDeclaration(
1624
+ void 0,
1625
+ false,
1626
+ this.factory.createNamedExports([])
1627
+ )
1628
+ );
1629
+ const sourceFile = ts.createSourceFile(
1630
+ "generated.d.ts",
1631
+ "",
1632
+ ts.ScriptTarget.Latest,
1633
+ false,
1634
+ ts.ScriptKind.TS
1635
+ );
1636
+ if (statements.length > 0) {
1637
+ ts.addSyntheticLeadingComment(
1638
+ statements[0],
1639
+ ts.SyntaxKind.MultiLineCommentTrivia,
1640
+ " eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any ",
1641
+ true
1642
+ );
1643
+ ts.addSyntheticLeadingComment(
1644
+ statements[0],
1645
+ ts.SyntaxKind.MultiLineCommentTrivia,
1646
+ headerComment,
1647
+ true
1648
+ );
1649
+ }
1650
+ return this.factory.updateSourceFile(sourceFile, statements);
1651
+ }
1652
+ createImportStatement(imports, from) {
1653
+ if (imports.length === 1 && !from && imports[0].startsWith("@")) {
1654
+ return this.factory.createImportDeclaration(
1655
+ void 0,
1656
+ void 0,
1657
+ this.factory.createStringLiteral(imports[0]),
1658
+ void 0
1659
+ );
1660
+ }
1661
+ const fromModule = from || imports[0];
1662
+ const importNames = from ? imports : [];
1663
+ return this.factory.createImportDeclaration(
1664
+ void 0,
1665
+ importNames.length > 0 ? this.factory.createImportClause(
1666
+ false,
1667
+ void 0,
1668
+ this.factory.createNamedImports(
1669
+ importNames.map(
1670
+ (name) => this.factory.createImportSpecifier(
1671
+ false,
1672
+ void 0,
1673
+ this.factory.createIdentifier(name)
1674
+ )
1675
+ )
1676
+ )
1677
+ ) : void 0,
1678
+ this.factory.createStringLiteral(fromModule),
1679
+ void 0
1680
+ );
1681
+ }
1682
+ createTypeImportStatement(imports, from) {
1683
+ return this.factory.createImportDeclaration(
1684
+ void 0,
1685
+ this.factory.createImportClause(
1686
+ true,
1687
+ // typeOnly: true
1688
+ void 0,
1689
+ this.factory.createNamedImports(
1690
+ imports.map(
1691
+ (name) => this.factory.createImportSpecifier(
1692
+ false,
1693
+ void 0,
1694
+ this.factory.createIdentifier(name)
1695
+ )
1696
+ )
1697
+ )
1698
+ ),
1699
+ this.factory.createStringLiteral(from),
1700
+ void 0
1701
+ );
1702
+ }
1703
+ groupActionsByType(actions) {
1704
+ return actions.reduce(
1705
+ (acc, action) => {
1706
+ if (!acc[action.action_type]) {
1707
+ acc[action.action_type] = [];
1708
+ }
1709
+ acc[action.action_type].push(action);
1710
+ return acc;
1711
+ },
1712
+ {}
1713
+ );
1714
+ }
1715
+ createInputInterface(appName, action) {
1716
+ const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(
1717
+ this.sanitizeActionName(action.key)
1718
+ )}Inputs`;
1719
+ const properties = action.inputFields.map((field) => {
1720
+ const fieldType = this.mapFieldTypeToTypeNode(field);
1721
+ const isOptional = !field.required;
1722
+ let property = this.factory.createPropertySignature(
1723
+ void 0,
1724
+ this.sanitizeFieldName(field.key),
1725
+ isOptional ? this.factory.createToken(ts.SyntaxKind.QuestionToken) : void 0,
1726
+ fieldType
1727
+ );
1728
+ if (field.helpText) {
1729
+ property = ts.addSyntheticLeadingComment(
1730
+ property,
1731
+ ts.SyntaxKind.MultiLineCommentTrivia,
1732
+ `* ${this.escapeComment(field.helpText)} `,
1733
+ true
1734
+ );
1735
+ }
1736
+ return property;
1737
+ });
1738
+ return this.factory.createInterfaceDeclaration(
1739
+ void 0,
1740
+ inputTypeName,
1741
+ void 0,
1742
+ void 0,
1743
+ properties
1744
+ );
1745
+ }
1746
+ createActionInterface(appName, actionType, typeActions) {
1747
+ const typeName = `${appName}${this.capitalize(actionType)}Actions`;
1748
+ const methods = typeActions.map((action) => {
1749
+ const actionName = this.sanitizeActionName(action.key);
1750
+ let methodSignature;
1751
+ if (action.inputFields.length > 0) {
1752
+ const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(
1753
+ this.sanitizeActionName(action.key)
1754
+ )}Inputs`;
1755
+ const inputsType = this.factory.createTypeLiteralNode([
1756
+ this.factory.createPropertySignature(
1757
+ void 0,
1758
+ "inputs",
1759
+ void 0,
1760
+ this.factory.createTypeReferenceNode(inputTypeName)
1761
+ )
1762
+ ]);
1763
+ const omitType = this.factory.createTypeReferenceNode("Omit", [
1764
+ this.factory.createTypeReferenceNode("ActionExecutionOptions"),
1765
+ this.factory.createLiteralTypeNode(
1766
+ this.factory.createStringLiteral("inputs")
1767
+ )
1768
+ ]);
1769
+ const optionsType = this.factory.createIntersectionTypeNode([
1770
+ inputsType,
1771
+ omitType
1772
+ ]);
1773
+ methodSignature = this.factory.createMethodSignature(
1774
+ void 0,
1775
+ actionName,
1776
+ void 0,
1777
+ void 0,
1778
+ [
1779
+ this.factory.createParameterDeclaration(
1780
+ void 0,
1781
+ void 0,
1782
+ "options",
1783
+ void 0,
1784
+ optionsType
1785
+ )
1786
+ ],
1787
+ this.factory.createTypeReferenceNode("Promise", [
1788
+ this.factory.createTypeReferenceNode("ActionExecutionResult")
1789
+ ])
1790
+ );
1791
+ } else {
1792
+ const genericInputsType = this.factory.createTypeLiteralNode([
1793
+ this.factory.createPropertySignature(
1794
+ void 0,
1795
+ "inputs",
1796
+ this.factory.createToken(ts.SyntaxKind.QuestionToken),
1797
+ this.factory.createTypeReferenceNode("Record", [
1798
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
1799
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
1800
+ ])
1801
+ )
1802
+ ]);
1803
+ const intersectionType = this.factory.createIntersectionTypeNode([
1804
+ genericInputsType,
1805
+ this.factory.createTypeReferenceNode("ActionExecutionOptions")
1806
+ ]);
1807
+ methodSignature = this.factory.createMethodSignature(
1808
+ void 0,
1809
+ actionName,
1810
+ void 0,
1811
+ void 0,
1812
+ [
1813
+ this.factory.createParameterDeclaration(
1814
+ void 0,
1815
+ void 0,
1816
+ "options",
1817
+ this.factory.createToken(ts.SyntaxKind.QuestionToken),
1818
+ intersectionType
1819
+ )
1820
+ ],
1821
+ this.factory.createTypeReferenceNode("Promise", [
1822
+ this.factory.createTypeReferenceNode("ActionExecutionResult")
1823
+ ])
1824
+ );
1825
+ }
1826
+ if (action.description) {
1827
+ methodSignature = ts.addSyntheticLeadingComment(
1828
+ methodSignature,
1829
+ ts.SyntaxKind.MultiLineCommentTrivia,
1830
+ `* ${this.escapeComment(action.description)} `,
1831
+ true
1832
+ );
1833
+ }
1834
+ return methodSignature;
1835
+ });
1836
+ return this.factory.createInterfaceDeclaration(
1837
+ void 0,
1838
+ typeName,
1839
+ void 0,
1840
+ void 0,
1841
+ methods
1842
+ );
1843
+ }
1844
+ createAppProxyInterface(appName, actionsByType) {
1845
+ const properties = [
1846
+ ...Object.keys(actionsByType).map(
1847
+ (actionType) => this.factory.createPropertySignature(
1848
+ void 0,
1849
+ actionType,
1850
+ void 0,
1851
+ this.factory.createTypeReferenceNode(
1852
+ `${appName}${this.capitalize(actionType)}Actions`
1853
+ )
1854
+ )
1855
+ ),
1856
+ // Always include fetch method for authenticated HTTP requests
1857
+ this.createFetchMethodProperty()
1858
+ ];
1859
+ return this.factory.createInterfaceDeclaration(
1860
+ void 0,
1861
+ `${appName}AppProxy`,
1862
+ void 0,
1863
+ void 0,
1864
+ properties
1865
+ );
1866
+ }
1867
+ createFetchMethodProperty() {
1868
+ let property = this.factory.createPropertySignature(
1869
+ void 0,
1870
+ "fetch",
1871
+ void 0,
1872
+ this.factory.createFunctionTypeNode(
1873
+ void 0,
1874
+ [
1875
+ this.factory.createParameterDeclaration(
1876
+ void 0,
1877
+ void 0,
1878
+ "url",
1879
+ void 0,
1880
+ this.factory.createUnionTypeNode([
1881
+ this.factory.createTypeReferenceNode("string"),
1882
+ this.factory.createTypeReferenceNode("URL")
1883
+ ])
1884
+ ),
1885
+ this.factory.createParameterDeclaration(
1886
+ void 0,
1887
+ void 0,
1888
+ "init",
1889
+ this.factory.createToken(ts.SyntaxKind.QuestionToken),
1890
+ this.factory.createTypeReferenceNode("ZapierFetchInitOptions")
1891
+ )
1892
+ ],
1893
+ this.factory.createTypeReferenceNode("Promise", [
1894
+ this.factory.createTypeReferenceNode("Response")
1895
+ ])
1896
+ )
1897
+ );
1898
+ property = ts.addSyntheticLeadingComment(
1899
+ property,
1900
+ ts.SyntaxKind.MultiLineCommentTrivia,
1901
+ "* Make authenticated HTTP requests through Zapier's Relay service ",
1902
+ true
1903
+ );
1904
+ return property;
1905
+ }
1906
+ createAppFactoryInterface(appName) {
1907
+ const callSignature = this.factory.createCallSignature(
1908
+ void 0,
1909
+ [
1910
+ this.factory.createParameterDeclaration(
1911
+ void 0,
1912
+ void 0,
1913
+ "options",
1914
+ void 0,
1915
+ this.factory.createTypeLiteralNode([
1916
+ this.factory.createPropertySignature(
1917
+ void 0,
1918
+ "authenticationId",
1919
+ void 0,
1920
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)
1921
+ )
1922
+ ])
1923
+ )
1924
+ ],
1925
+ this.factory.createTypeReferenceNode(`${appName}AppProxy`)
1926
+ );
1927
+ return this.factory.createInterfaceDeclaration(
1928
+ void 0,
1929
+ `${appName}AppFactory`,
1930
+ void 0,
1931
+ void 0,
1932
+ [callSignature]
1933
+ );
1934
+ }
1935
+ createAppWithFactoryType(appName) {
1936
+ return this.factory.createTypeAliasDeclaration(
1937
+ void 0,
1938
+ `${appName}AppWithFactory`,
1939
+ void 0,
1940
+ this.factory.createIntersectionTypeNode([
1941
+ this.factory.createTypeReferenceNode(`${appName}AppFactory`),
1942
+ this.factory.createTypeReferenceNode(`${appName}AppProxy`)
1943
+ ])
1944
+ );
1945
+ }
1946
+ createModuleAugmentation(appKey, appName) {
1947
+ return this.factory.createModuleDeclaration(
1948
+ [this.factory.createToken(ts.SyntaxKind.DeclareKeyword)],
1949
+ this.factory.createStringLiteral("@zapier/zapier-sdk"),
1950
+ this.factory.createModuleBlock([
1951
+ this.factory.createInterfaceDeclaration(
1952
+ void 0,
1953
+ "ZapierSdkApps",
1954
+ void 0,
1955
+ void 0,
1956
+ [
1957
+ this.factory.createPropertySignature(
1958
+ void 0,
1959
+ appKey,
1960
+ void 0,
1961
+ this.factory.createTypeReferenceNode(`${appName}AppWithFactory`)
1962
+ )
1963
+ ]
1964
+ )
1965
+ ])
1966
+ );
1967
+ }
1968
+ mapFieldTypeToTypeNode(field) {
1969
+ if (field.choices && field.choices.length > 0) {
1970
+ const choiceValues = field.choices.filter(
1971
+ (choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
1972
+ ).map(
1973
+ (choice) => typeof choice.value === "string" ? this.factory.createLiteralTypeNode(
1974
+ this.factory.createStringLiteral(choice.value)
1975
+ ) : this.factory.createLiteralTypeNode(
1976
+ this.factory.createNumericLiteral(String(choice.value))
1977
+ )
1978
+ );
1979
+ if (choiceValues.length > 0) {
1980
+ return this.factory.createUnionTypeNode(choiceValues);
1981
+ }
1982
+ }
1983
+ switch (field.type?.toLowerCase()) {
1984
+ case "string":
1985
+ case "text":
1986
+ case "email":
1987
+ case "url":
1988
+ case "password":
1989
+ case "datetime":
1990
+ case "date":
1991
+ case "file":
1992
+ return this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
1993
+ case "integer":
1994
+ case "number":
1995
+ return this.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
1996
+ case "boolean":
1997
+ return this.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
1998
+ case "array":
1999
+ return this.factory.createArrayTypeNode(
2000
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
2001
+ );
2002
+ case "object":
2003
+ return this.factory.createTypeReferenceNode("Record", [
2004
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
2005
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)
2006
+ ]);
2007
+ default:
2008
+ return this.factory.createUnionTypeNode([
2009
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
2010
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
2011
+ this.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword)
2012
+ ]);
2013
+ }
2014
+ }
2015
+ generateEmptyTypesFile(appKey, version) {
2016
+ const appName = this.capitalize(appKey);
2017
+ const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
2018
+ return `/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */
2019
+ /**
2020
+ * Auto-generated TypeScript types for Zapier ${appKey} actions
2021
+ ${versionComment}
2022
+ * Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
2023
+ *
2024
+ * No actions found for this app.
2025
+ */
2026
+
2027
+ import type { ActionExecutionOptions, ActionExecutionResult, ZapierFetchInitOptions } from '@zapier/zapier-sdk'
2028
+
2029
+ interface ${appName}AppProxy {
2030
+ /** Make authenticated HTTP requests through Zapier's Relay service */
2031
+ fetch: (url: string | URL, init?: ZapierFetchInitOptions) => Promise<Response>
2032
+ }
2033
+
2034
+ interface ${appName}AppFactory {
2035
+ (options: { authenticationId: number }): ${appName}AppProxy
2036
+ }
2037
+
2038
+ type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
2039
+
2040
+ declare module "@zapier/zapier-sdk" {
2041
+ interface ZapierSdkApps {
2042
+ ${appKey}: ${appName}AppWithFactory
2043
+ }
2044
+ }
2045
+ `;
2046
+ }
2047
+ capitalize(str) {
2048
+ return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
2049
+ }
2050
+ sanitizeActionName(actionKey) {
2051
+ let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
2052
+ if (/^[0-9]/.test(sanitized)) {
2053
+ sanitized = "_" + sanitized;
2054
+ }
2055
+ return sanitized;
2056
+ }
2057
+ sanitizeFieldName(fieldKey) {
2058
+ let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
2059
+ if (/^[0-9]/.test(sanitized)) {
2060
+ sanitized = "_" + sanitized;
2061
+ }
2062
+ return sanitized;
2063
+ }
2064
+ escapeComment(comment) {
2065
+ return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
2066
+ }
2067
+ };
2068
+ async function detectTypesOutputDirectory() {
2069
+ const candidates = ["src", "lib"];
2070
+ for (const candidate of candidates) {
2071
+ try {
2072
+ await access(candidate);
2073
+ return join(candidate, "zapier", "apps");
2074
+ } catch {
2075
+ }
2076
+ }
2077
+ return "./zapier/apps/";
2078
+ }
2079
+ var addPlugin = ({ sdk: sdk2, context }) => {
2080
+ const add = createFunction(async function add2(options) {
2081
+ const {
2082
+ appKeys,
2083
+ authenticationIds,
2084
+ configPath,
2085
+ typesOutput = await detectTypesOutputDirectory()
2086
+ } = options;
2087
+ const resolvedTypesOutput = resolve(typesOutput);
2088
+ await mkdir(resolvedTypesOutput, { recursive: true });
2089
+ console.log(`\u{1F4E6} Looking up ${appKeys.length} app(s)...`);
2090
+ const appsIterator = sdk2.listApps({ appKeys }).items();
2091
+ const apps = [];
2092
+ for await (const app of appsIterator) {
2093
+ apps.push(app);
2094
+ }
2095
+ if (apps.length === 0) {
2096
+ console.warn("\u26A0\uFE0F No apps found");
2097
+ return;
2098
+ }
2099
+ let authentications = [];
2100
+ if (authenticationIds && authenticationIds.length > 0) {
2101
+ console.log(
2102
+ `\u{1F510} Looking up ${authenticationIds.length} authentication(s)...`
2103
+ );
2104
+ const authsIterator = sdk2.listAuthentications({ authenticationIds }).items();
2105
+ for await (const auth of authsIterator) {
2106
+ authentications.push(auth);
2107
+ }
2108
+ console.log(`\u{1F510} Found ${authentications.length} authentication(s)`);
2109
+ }
2110
+ for (const app of apps) {
2111
+ const appSlugAndKey = app.slug ? `${app.slug} (${app.key})` : app.key;
2112
+ console.log(`\u{1F4E6} Adding ${appSlugAndKey}...`);
2113
+ try {
2114
+ if (!app.version) {
2115
+ console.warn(
2116
+ `\u26A0\uFE0F Invalid implementation ID format for '${appSlugAndKey}': ${app.implementation_id}. Expected format: <implementationName>@<version>. Skipping...`
2117
+ );
2118
+ continue;
2119
+ }
2120
+ const [manifestKey] = await context.updateManifestEntry(
2121
+ app.key,
2122
+ {
2123
+ implementationName: app.key,
2124
+ version: app.version
2125
+ },
2126
+ configPath
2127
+ );
2128
+ console.log(
2129
+ `\u{1F4DD} Locked ${appSlugAndKey} to ${app.key}@${app.version} using key '${manifestKey}'`
2130
+ );
2131
+ let authenticationId;
2132
+ if (authentications.length > 0) {
2133
+ const matchingAuth = authentications.find((auth) => {
2134
+ return auth.app_key === app.key;
2135
+ });
2136
+ if (matchingAuth) {
2137
+ authenticationId = matchingAuth.id;
2138
+ console.log(
2139
+ `\u{1F510} Using authentication ${authenticationId} (${matchingAuth.title}) for ${appSlugAndKey}`
2140
+ );
2141
+ } else {
2142
+ console.warn(
2143
+ `\u26A0\uFE0F No matching authentication found for ${appSlugAndKey}`
2144
+ );
2145
+ }
2146
+ }
2147
+ const typesPath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
2148
+ try {
2149
+ const generator = new AstTypeGenerator();
2150
+ const typeDefinitions = await generator.generateTypes({
2151
+ appKey: manifestKey,
2152
+ authenticationId,
2153
+ sdk: sdk2
2154
+ });
2155
+ await writeFile(typesPath, typeDefinitions, "utf8");
2156
+ console.log(`\u{1F527} Generated types for ${manifestKey} at ${typesPath}`);
2157
+ } catch (error) {
2158
+ console.warn(
2159
+ `\u26A0\uFE0F Failed to generate types for ${appSlugAndKey}: ${error}`
2160
+ );
2161
+ }
2162
+ } catch (error) {
2163
+ console.warn(`\u26A0\uFE0F Failed to process ${appSlugAndKey}: ${error}`);
2164
+ }
2165
+ }
2166
+ console.log(`\u2705 Added ${apps.length} app(s) to manifest`);
2167
+ }, AddSchema);
2168
+ return {
2169
+ add,
1653
2170
  context: {
1654
2171
  meta: {
1655
- getConfigPath: {
2172
+ add: {
1656
2173
  categories: ["utility"],
1657
- inputSchema: GetConfigPathSchema
2174
+ inputSchema: AddSchema
1658
2175
  }
1659
2176
  }
1660
2177
  }
@@ -1666,9 +2183,9 @@ function createZapierCliSdk(options = {}) {
1666
2183
  let sdk2 = createZapierSdkWithoutRegistry({
1667
2184
  debug: options.debug
1668
2185
  });
1669
- sdk2 = sdk2.addPlugin(generateTypesPlugin);
1670
2186
  sdk2 = sdk2.addPlugin(bundleCodePlugin);
1671
- sdk2 = sdk2.addPlugin(getConfigPathPlugin);
2187
+ sdk2 = sdk2.addPlugin(getLoginConfigPathPlugin);
2188
+ sdk2 = sdk2.addPlugin(addPlugin);
1672
2189
  sdk2 = sdk2.addPlugin(mcpPlugin);
1673
2190
  sdk2 = sdk2.addPlugin(loginPlugin);
1674
2191
  sdk2 = sdk2.addPlugin(logoutPlugin);
@@ -1678,7 +2195,7 @@ function createZapierCliSdk(options = {}) {
1678
2195
 
1679
2196
  // package.json
1680
2197
  var package_default = {
1681
- version: "0.8.4"};
2198
+ version: "0.10.0"};
1682
2199
 
1683
2200
  // src/cli.ts
1684
2201
  var program = new Command();