@zapier/zapier-sdk-cli 0.59.0 → 0.59.2

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 (174) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/cli.cjs +2 -2
  3. package/dist/cli.mjs +2 -2
  4. package/dist/experimental.cjs +1 -1
  5. package/dist/experimental.mjs +1 -1
  6. package/dist/index.cjs +2 -2
  7. package/dist/index.mjs +2 -2
  8. package/package.json +4 -4
  9. package/dist/package.json +0 -121
  10. package/dist/src/cli.d.ts +0 -2
  11. package/dist/src/cli.js +0 -219
  12. package/dist/src/experimental.d.ts +0 -33
  13. package/dist/src/experimental.js +0 -86
  14. package/dist/src/generators/ast-generator.d.ts +0 -41
  15. package/dist/src/generators/ast-generator.js +0 -405
  16. package/dist/src/index.d.ts +0 -5
  17. package/dist/src/index.js +0 -5
  18. package/dist/src/login/config.d.ts +0 -4
  19. package/dist/src/login/config.js +0 -21
  20. package/dist/src/login/credentials-revoke.d.ts +0 -14
  21. package/dist/src/login/credentials-revoke.js +0 -95
  22. package/dist/src/login/credentials-store.d.ts +0 -60
  23. package/dist/src/login/credentials-store.js +0 -181
  24. package/dist/src/login/filesystem-cache.d.ts +0 -25
  25. package/dist/src/login/filesystem-cache.js +0 -195
  26. package/dist/src/login/index.d.ts +0 -110
  27. package/dist/src/login/index.js +0 -424
  28. package/dist/src/login/keychain.d.ts +0 -18
  29. package/dist/src/login/keychain.js +0 -74
  30. package/dist/src/login/legacy-jwt.d.ts +0 -4
  31. package/dist/src/login/legacy-jwt.js +0 -18
  32. package/dist/src/login.d.ts +0 -10
  33. package/dist/src/login.js +0 -10
  34. package/dist/src/paths.d.ts +0 -1
  35. package/dist/src/paths.js +0 -6
  36. package/dist/src/plugins/add/index.d.ts +0 -254
  37. package/dist/src/plugins/add/index.js +0 -95
  38. package/dist/src/plugins/add/schemas.d.ts +0 -8
  39. package/dist/src/plugins/add/schemas.js +0 -22
  40. package/dist/src/plugins/auth/credentials-base-url.d.ts +0 -11
  41. package/dist/src/plugins/auth/credentials-base-url.js +0 -24
  42. package/dist/src/plugins/buildManifest/index.d.ts +0 -120
  43. package/dist/src/plugins/buildManifest/index.js +0 -71
  44. package/dist/src/plugins/buildManifest/schemas.d.ts +0 -44
  45. package/dist/src/plugins/buildManifest/schemas.js +0 -17
  46. package/dist/src/plugins/bundleCode/index.d.ts +0 -23
  47. package/dist/src/plugins/bundleCode/index.js +0 -62
  48. package/dist/src/plugins/bundleCode/schemas.d.ts +0 -10
  49. package/dist/src/plugins/bundleCode/schemas.js +0 -19
  50. package/dist/src/plugins/cliOverrides/index.d.ts +0 -21
  51. package/dist/src/plugins/cliOverrides/index.js +0 -17
  52. package/dist/src/plugins/curl/index.d.ts +0 -76
  53. package/dist/src/plugins/curl/index.js +0 -236
  54. package/dist/src/plugins/curl/schemas.d.ts +0 -40
  55. package/dist/src/plugins/curl/schemas.js +0 -108
  56. package/dist/src/plugins/curl/utils.d.ts +0 -34
  57. package/dist/src/plugins/curl/utils.js +0 -150
  58. package/dist/src/plugins/drainTriggerInbox/index.d.ts +0 -46
  59. package/dist/src/plugins/drainTriggerInbox/index.js +0 -178
  60. package/dist/src/plugins/feedback/index.d.ts +0 -24
  61. package/dist/src/plugins/feedback/index.js +0 -52
  62. package/dist/src/plugins/feedback/schemas.d.ts +0 -5
  63. package/dist/src/plugins/feedback/schemas.js +0 -8
  64. package/dist/src/plugins/generateAppTypes/index.d.ts +0 -265
  65. package/dist/src/plugins/generateAppTypes/index.js +0 -129
  66. package/dist/src/plugins/generateAppTypes/schemas.d.ts +0 -58
  67. package/dist/src/plugins/generateAppTypes/schemas.js +0 -21
  68. package/dist/src/plugins/getLoginConfigPath/index.d.ts +0 -16
  69. package/dist/src/plugins/getLoginConfigPath/index.js +0 -9
  70. package/dist/src/plugins/getLoginConfigPath/schemas.d.ts +0 -3
  71. package/dist/src/plugins/getLoginConfigPath/schemas.js +0 -5
  72. package/dist/src/plugins/index.d.ts +0 -15
  73. package/dist/src/plugins/index.js +0 -15
  74. package/dist/src/plugins/init/display.d.ts +0 -9
  75. package/dist/src/plugins/init/display.js +0 -72
  76. package/dist/src/plugins/init/index.d.ts +0 -21
  77. package/dist/src/plugins/init/index.js +0 -56
  78. package/dist/src/plugins/init/schemas.d.ts +0 -9
  79. package/dist/src/plugins/init/schemas.js +0 -19
  80. package/dist/src/plugins/init/steps.d.ts +0 -39
  81. package/dist/src/plugins/init/steps.js +0 -141
  82. package/dist/src/plugins/init/types.d.ts +0 -31
  83. package/dist/src/plugins/init/types.js +0 -1
  84. package/dist/src/plugins/init/utils.d.ts +0 -48
  85. package/dist/src/plugins/init/utils.js +0 -135
  86. package/dist/src/plugins/login/index.d.ts +0 -25
  87. package/dist/src/plugins/login/index.js +0 -12
  88. package/dist/src/plugins/login/schemas.d.ts +0 -9
  89. package/dist/src/plugins/login/schemas.js +0 -27
  90. package/dist/src/plugins/logout/index.d.ts +0 -30
  91. package/dist/src/plugins/logout/index.js +0 -33
  92. package/dist/src/plugins/logout/schemas.d.ts +0 -2
  93. package/dist/src/plugins/logout/schemas.js +0 -4
  94. package/dist/src/plugins/mcp/index.d.ts +0 -28
  95. package/dist/src/plugins/mcp/index.js +0 -24
  96. package/dist/src/plugins/mcp/schemas.d.ts +0 -5
  97. package/dist/src/plugins/mcp/schemas.js +0 -10
  98. package/dist/src/plugins/signup/index.d.ts +0 -25
  99. package/dist/src/plugins/signup/index.js +0 -12
  100. package/dist/src/plugins/signup/schemas.d.ts +0 -9
  101. package/dist/src/plugins/signup/schemas.js +0 -26
  102. package/dist/src/plugins/signup/test-harness.d.ts +0 -34
  103. package/dist/src/plugins/signup/test-harness.js +0 -76
  104. package/dist/src/plugins/watchTriggerInbox/index.d.ts +0 -46
  105. package/dist/src/plugins/watchTriggerInbox/index.js +0 -166
  106. package/dist/src/sdk.d.ts +0 -17
  107. package/dist/src/sdk.js +0 -67
  108. package/dist/src/telemetry/builders.d.ts +0 -44
  109. package/dist/src/telemetry/builders.js +0 -59
  110. package/dist/src/telemetry/events.d.ts +0 -40
  111. package/dist/src/telemetry/events.js +0 -4
  112. package/dist/src/types/sdk.d.ts +0 -6
  113. package/dist/src/types/sdk.js +0 -1
  114. package/dist/src/utils/api/client.d.ts +0 -15
  115. package/dist/src/utils/api/client.js +0 -27
  116. package/dist/src/utils/approval-errors.d.ts +0 -1
  117. package/dist/src/utils/approval-errors.js +0 -9
  118. package/dist/src/utils/approval-progress.d.ts +0 -12
  119. package/dist/src/utils/approval-progress.js +0 -179
  120. package/dist/src/utils/auth/account-auth.d.ts +0 -33
  121. package/dist/src/utils/auth/account-auth.js +0 -302
  122. package/dist/src/utils/auth/client-credentials.d.ts +0 -26
  123. package/dist/src/utils/auth/client-credentials.js +0 -67
  124. package/dist/src/utils/auth/oauth-callback.d.ts +0 -6
  125. package/dist/src/utils/auth/oauth-callback.js +0 -28
  126. package/dist/src/utils/auth/oauth-errors.d.ts +0 -2
  127. package/dist/src/utils/auth/oauth-errors.js +0 -39
  128. package/dist/src/utils/auth/oauth-flow.d.ts +0 -37
  129. package/dist/src/utils/auth/oauth-flow.js +0 -313
  130. package/dist/src/utils/auth/oauth-transaction.d.ts +0 -35
  131. package/dist/src/utils/auth/oauth-transaction.js +0 -69
  132. package/dist/src/utils/cli-generator-utils.d.ts +0 -14
  133. package/dist/src/utils/cli-generator-utils.js +0 -122
  134. package/dist/src/utils/cli-generator.d.ts +0 -4
  135. package/dist/src/utils/cli-generator.js +0 -831
  136. package/dist/src/utils/cli-options.d.ts +0 -16
  137. package/dist/src/utils/cli-options.js +0 -34
  138. package/dist/src/utils/cli-renderer.d.ts +0 -53
  139. package/dist/src/utils/cli-renderer.js +0 -265
  140. package/dist/src/utils/constants.d.ts +0 -3
  141. package/dist/src/utils/constants.js +0 -5
  142. package/dist/src/utils/directory-detection.d.ts +0 -5
  143. package/dist/src/utils/directory-detection.js +0 -21
  144. package/dist/src/utils/errors.d.ts +0 -33
  145. package/dist/src/utils/errors.js +0 -36
  146. package/dist/src/utils/extensions.d.ts +0 -20
  147. package/dist/src/utils/extensions.js +0 -66
  148. package/dist/src/utils/getCallablePromise.d.ts +0 -6
  149. package/dist/src/utils/getCallablePromise.js +0 -14
  150. package/dist/src/utils/log.d.ts +0 -8
  151. package/dist/src/utils/log.js +0 -26
  152. package/dist/src/utils/manifest-helpers.d.ts +0 -10
  153. package/dist/src/utils/manifest-helpers.js +0 -19
  154. package/dist/src/utils/non-interactive.d.ts +0 -14
  155. package/dist/src/utils/non-interactive.js +0 -15
  156. package/dist/src/utils/package-manager-detector.d.ts +0 -18
  157. package/dist/src/utils/package-manager-detector.js +0 -72
  158. package/dist/src/utils/parameter-resolver.d.ts +0 -179
  159. package/dist/src/utils/parameter-resolver.js +0 -1554
  160. package/dist/src/utils/retry.d.ts +0 -6
  161. package/dist/src/utils/retry.js +0 -21
  162. package/dist/src/utils/schema-formatter.d.ts +0 -11
  163. package/dist/src/utils/schema-formatter.js +0 -131
  164. package/dist/src/utils/serializeAsync.d.ts +0 -2
  165. package/dist/src/utils/serializeAsync.js +0 -16
  166. package/dist/src/utils/spinner.d.ts +0 -1
  167. package/dist/src/utils/spinner.js +0 -21
  168. package/dist/src/utils/string-utils.d.ts +0 -1
  169. package/dist/src/utils/string-utils.js +0 -6
  170. package/dist/src/utils/triggerDrain.d.ts +0 -144
  171. package/dist/src/utils/triggerDrain.js +0 -351
  172. package/dist/src/utils/version-checker.d.ts +0 -17
  173. package/dist/src/utils/version-checker.js +0 -154
  174. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,405 +0,0 @@
1
- import * as ts from "typescript";
2
- import { toSnakeCase, batch } from "@zapier/zapier-sdk";
3
- /**
4
- * AST-based TypeScript type generator using the TypeScript Compiler API
5
- */
6
- export class AstTypeGenerator {
7
- constructor() {
8
- this.factory = ts.factory;
9
- this.printer = ts.createPrinter({
10
- newLine: ts.NewLineKind.LineFeed,
11
- removeComments: false,
12
- omitTrailingSemicolon: false,
13
- });
14
- }
15
- /**
16
- * Generate TypeScript types using AST for a specific app
17
- */
18
- async generateTypes(options) {
19
- const { app, connectionId, sdk } = options;
20
- // Fetch all actions for the app using implementation_id for correct versioning
21
- const actionsResult = await sdk.listActions({
22
- appKey: app.implementation_id,
23
- });
24
- const actions = actionsResult.data;
25
- // Fetch input fields for each action
26
- const actionsWithFields = [];
27
- // Fetch all input fields with concurrency limiting for better reliability
28
- // Using batch() instead of Promise.allSettled() prevents overwhelming the API
29
- // and triggering rate limits when apps have many actions
30
- const inputFieldsTasks = actions.map((action) => () => sdk.listActionInputFields({
31
- appKey: app.implementation_id,
32
- actionKey: action.key,
33
- actionType: action.action_type,
34
- connectionId: connectionId,
35
- }));
36
- const results = await batch(inputFieldsTasks, {
37
- concurrency: 50, // Limit to 50 concurrent requests
38
- retry: true, // Automatically retry transient failures
39
- timeoutMs: 180000, // 3 minute overall timeout
40
- taskTimeoutMs: 30000, // 30 seconds per-task timeout (API calls shouldn't take longer)
41
- });
42
- const failedActions = [];
43
- results.forEach((result, i) => {
44
- const action = actions[i];
45
- if (result.status === "fulfilled") {
46
- actionsWithFields.push({
47
- ...action,
48
- inputFields: result.value.data,
49
- name: action.title || action.key,
50
- });
51
- }
52
- else {
53
- failedActions.push(`${action.key} (${action.action_type}): ${result.reason?.message || "Unknown error"}`);
54
- actionsWithFields.push({
55
- ...action,
56
- inputFields: [],
57
- name: action.title || action.key,
58
- app_key: action.app_key || app.implementation_id,
59
- action_type: action.action_type || "write",
60
- title: action.title || action.key,
61
- type: "action",
62
- description: action.description || "",
63
- });
64
- }
65
- });
66
- if (failedActions.length > 0) {
67
- console.warn(`Failed to fetch input fields for ${failedActions.length} action(s):`);
68
- failedActions.forEach((failedAction) => {
69
- console.warn(` - ${failedAction}`);
70
- });
71
- }
72
- // Generate TypeScript AST nodes
73
- const sourceFile = this.createSourceFile(app, actionsWithFields);
74
- // Print the AST to string
75
- return this.printer.printFile(sourceFile);
76
- }
77
- createSourceFile(app, actions) {
78
- const appName = this.getPreferredAppName(app);
79
- const versionComment = ` * Generated for ${app.implementation_id}`;
80
- const preferredKey = this.getPreferredProgrammaticKey(app);
81
- const myVariableName = `my${appName}`;
82
- // Create header comment
83
- const headerComment = `Auto-generated TypeScript types for Zapier ${app.key} actions
84
- ${versionComment.slice(3)}
85
- Generated on: ${new Date().toISOString()}
86
-
87
- This file automatically augments the base SDK types when present.
88
- No manual imports or type casting required.
89
-
90
- Usage:
91
- import { createZapierSdk } from "@zapier/zapier-sdk";
92
-
93
- const zapier = createZapierSdk();
94
- // Types are automatically available:
95
- await zapier.apps.${preferredKey}.search.user_by_email({ connection: 123, inputs: { email } })
96
-
97
- // Factory usage (pinned connection):
98
- const ${myVariableName} = zapier.apps.${preferredKey}({ connection: 123 })
99
- await ${myVariableName}.search.user_by_email({ inputs: { email } })`;
100
- const statements = [
101
- // Import the SDK to activate module augmentation
102
- this.createImportStatement(["@zapier/zapier-sdk"]),
103
- // Import types we'll use
104
- this.createTypeImportStatement([
105
- "ActionExecutionOptions",
106
- "ActionExecutionResult",
107
- "AppFactoryInput",
108
- "ZapierFetchInitOptions",
109
- ], "@zapier/zapier-sdk"),
110
- ];
111
- // Group actions by type
112
- const actionsByType = this.groupActionsByType(actions);
113
- // Generate input interfaces for each action
114
- actions.forEach((action) => {
115
- if (action.inputFields.length > 0) {
116
- const inputInterface = this.createInputInterface(appName, action);
117
- statements.push(inputInterface);
118
- }
119
- });
120
- // Generate action type interfaces
121
- Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
122
- const actionInterface = this.createActionInterface(appName, actionType, typeActions);
123
- statements.push(actionInterface);
124
- });
125
- // Generate app proxy interface
126
- const appProxyInterface = this.createAppProxyInterface(appName, actionsByType);
127
- statements.push(appProxyInterface);
128
- // Generate app factory interface
129
- const appFactoryInterface = this.createAppFactoryInterface(appName);
130
- statements.push(appFactoryInterface);
131
- // Generate combined app type
132
- const appWithFactoryType = this.createAppWithFactoryType(appName);
133
- statements.push(appWithFactoryType);
134
- // Generate module augmentation for automatic type integration
135
- const allKeys = this.getAllKeys(app);
136
- const moduleAugmentation = this.createModuleAugmentation(allKeys, appName);
137
- statements.push(moduleAugmentation);
138
- // Add empty export to make this a module
139
- statements.push(this.factory.createExportDeclaration(undefined, false, this.factory.createNamedExports([])));
140
- // Create source file
141
- const sourceFile = ts.createSourceFile("generated.d.ts", "", ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
142
- // Add the header comment and ESLint disable as leading trivia to the first statement
143
- if (statements.length > 0) {
144
- // Add ESLint disable comment
145
- ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.MultiLineCommentTrivia, " eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any ", true);
146
- // Add header comment
147
- ts.addSyntheticLeadingComment(statements[0], ts.SyntaxKind.MultiLineCommentTrivia, headerComment, true);
148
- }
149
- return this.factory.updateSourceFile(sourceFile, statements);
150
- }
151
- createImportStatement(imports, from) {
152
- // Handle side-effect only import (no imports, just the module path)
153
- if (imports.length === 1 && !from && imports[0].startsWith("@")) {
154
- return this.factory.createImportDeclaration(undefined, undefined, this.factory.createStringLiteral(imports[0]), undefined);
155
- }
156
- const fromModule = from || imports[0];
157
- const importNames = from ? imports : [];
158
- return this.factory.createImportDeclaration(undefined, importNames.length > 0
159
- ? this.factory.createImportClause(false, undefined, this.factory.createNamedImports(importNames.map((name) => this.factory.createImportSpecifier(false, undefined, this.factory.createIdentifier(name)))))
160
- : undefined, this.factory.createStringLiteral(fromModule), undefined);
161
- }
162
- createTypeImportStatement(imports, from) {
163
- return this.factory.createImportDeclaration(undefined, this.factory.createImportClause(true, // typeOnly: true
164
- undefined, this.factory.createNamedImports(imports.map((name) => this.factory.createImportSpecifier(false, undefined, this.factory.createIdentifier(name))))), this.factory.createStringLiteral(from), undefined);
165
- }
166
- groupActionsByType(actions) {
167
- return actions.reduce((acc, action) => {
168
- if (!acc[action.action_type]) {
169
- acc[action.action_type] = [];
170
- }
171
- acc[action.action_type].push(action);
172
- return acc;
173
- }, {});
174
- }
175
- createInputInterface(appName, action) {
176
- const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(this.sanitizeActionName(action.key))}Inputs`;
177
- const properties = action.inputFields.map((field) => {
178
- const fieldType = this.mapFieldTypeToTypeNode(field);
179
- const isOptional = !field.is_required;
180
- let property = this.factory.createPropertySignature(undefined, this.sanitizeFieldName(field.key), isOptional
181
- ? this.factory.createToken(ts.SyntaxKind.QuestionToken)
182
- : undefined, fieldType);
183
- // Add JSDoc comment if description exists
184
- if (field.description) {
185
- property = ts.addSyntheticLeadingComment(property, ts.SyntaxKind.MultiLineCommentTrivia, `* ${this.escapeComment(field.description)} `, true);
186
- }
187
- return property;
188
- });
189
- return this.factory.createInterfaceDeclaration(undefined, inputTypeName, undefined, undefined, properties);
190
- }
191
- createActionInterface(appName, actionType, typeActions) {
192
- const typeName = `${appName}${this.capitalize(actionType)}Actions`;
193
- const methods = typeActions.map((action) => {
194
- const actionName = this.sanitizeActionName(action.key);
195
- let methodSignature;
196
- if (action.inputFields.length > 0) {
197
- // Generate type-safe action method signature
198
- const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(this.sanitizeActionName(action.key))}Inputs`;
199
- const inputsType = this.factory.createTypeLiteralNode([
200
- this.factory.createPropertySignature(undefined, "inputs", undefined, this.factory.createTypeReferenceNode(inputTypeName)),
201
- ]);
202
- const omitType = this.factory.createTypeReferenceNode("Omit", [
203
- this.factory.createTypeReferenceNode("ActionExecutionOptions"),
204
- this.factory.createLiteralTypeNode(this.factory.createStringLiteral("inputs")),
205
- ]);
206
- const optionsType = this.factory.createIntersectionTypeNode([
207
- inputsType,
208
- omitType,
209
- ]);
210
- methodSignature = this.factory.createMethodSignature(undefined, actionName, undefined, undefined, [
211
- this.factory.createParameterDeclaration(undefined, undefined, "options", undefined, optionsType),
212
- ], this.factory.createTypeReferenceNode("Promise", [
213
- this.factory.createTypeReferenceNode("ActionExecutionResult"),
214
- ]));
215
- }
216
- else {
217
- // No specific input fields available - use generic Record<string, any> for inputs
218
- const genericInputsType = this.factory.createTypeLiteralNode([
219
- this.factory.createPropertySignature(undefined, "inputs", this.factory.createToken(ts.SyntaxKind.QuestionToken), this.factory.createTypeReferenceNode("Record", [
220
- this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
221
- this.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
222
- ])),
223
- ]);
224
- const intersectionType = this.factory.createIntersectionTypeNode([
225
- genericInputsType,
226
- this.factory.createTypeReferenceNode("ActionExecutionOptions"),
227
- ]);
228
- methodSignature = this.factory.createMethodSignature(undefined, actionName, undefined, undefined, [
229
- this.factory.createParameterDeclaration(undefined, undefined, "options", this.factory.createToken(ts.SyntaxKind.QuestionToken), intersectionType),
230
- ], this.factory.createTypeReferenceNode("Promise", [
231
- this.factory.createTypeReferenceNode("ActionExecutionResult"),
232
- ]));
233
- }
234
- // Add JSDoc comment if description exists
235
- if (action.description) {
236
- methodSignature = ts.addSyntheticLeadingComment(methodSignature, ts.SyntaxKind.MultiLineCommentTrivia, `* ${this.escapeComment(action.description)} `, true);
237
- }
238
- return methodSignature;
239
- });
240
- return this.factory.createInterfaceDeclaration(undefined, typeName, undefined, undefined, methods);
241
- }
242
- createAppProxyInterface(appName, actionsByType) {
243
- const properties = [
244
- ...Object.keys(actionsByType).map((actionType) => this.factory.createPropertySignature(undefined, actionType, undefined, this.factory.createTypeReferenceNode(`${appName}${this.capitalize(actionType)}Actions`))),
245
- // Always include fetch method for authenticated HTTP requests
246
- this.createFetchMethodProperty(),
247
- ];
248
- return this.factory.createInterfaceDeclaration(undefined, `${appName}AppProxy`, undefined, undefined, properties);
249
- }
250
- createFetchMethodProperty() {
251
- let property = this.factory.createPropertySignature(undefined, "fetch", undefined, this.factory.createFunctionTypeNode(undefined, [
252
- this.factory.createParameterDeclaration(undefined, undefined, "url", undefined, this.factory.createUnionTypeNode([
253
- this.factory.createTypeReferenceNode("string"),
254
- this.factory.createTypeReferenceNode("URL"),
255
- ])),
256
- this.factory.createParameterDeclaration(undefined, undefined, "init", this.factory.createToken(ts.SyntaxKind.QuestionToken), this.factory.createTypeReferenceNode("ZapierFetchInitOptions")),
257
- ], this.factory.createTypeReferenceNode("Promise", [
258
- this.factory.createTypeReferenceNode("Response"),
259
- ])));
260
- // Add JSDoc comment
261
- property = ts.addSyntheticLeadingComment(property, ts.SyntaxKind.MultiLineCommentTrivia, "* Make authenticated HTTP requests through Zapier's Relay service ", true);
262
- return property;
263
- }
264
- createAppFactoryInterface(appName) {
265
- const callSignature = this.factory.createCallSignature(undefined, [
266
- this.factory.createParameterDeclaration(undefined, undefined, "options", undefined, this.factory.createTypeReferenceNode("AppFactoryInput")),
267
- ], this.factory.createTypeReferenceNode(`${appName}AppProxy`));
268
- return this.factory.createInterfaceDeclaration(undefined, `${appName}AppFactory`, undefined, undefined, [callSignature]);
269
- }
270
- createAppWithFactoryType(appName) {
271
- return this.factory.createTypeAliasDeclaration(undefined, `${appName}AppWithFactory`, undefined, this.factory.createIntersectionTypeNode([
272
- this.factory.createTypeReferenceNode(`${appName}AppFactory`),
273
- this.factory.createTypeReferenceNode(`${appName}AppProxy`),
274
- ]));
275
- }
276
- createModuleAugmentation(appKeys, appName) {
277
- // Create: declare module "@zapier/zapier-sdk" { interface ZapierSdkApps { [appKey]: AppWithFactory } }
278
- // This creates a new interface that we can merge with ZapierSdk
279
- // Create properties for all keys (main key + other_keys)
280
- const properties = appKeys.map((appKey) => this.factory.createPropertySignature(undefined, this.createPropertyName(appKey), undefined, this.factory.createTypeReferenceNode(`${appName}AppWithFactory`)));
281
- return this.factory.createModuleDeclaration([this.factory.createToken(ts.SyntaxKind.DeclareKeyword)], this.factory.createStringLiteral("@zapier/zapier-sdk"), this.factory.createModuleBlock([
282
- this.factory.createInterfaceDeclaration(undefined, "ZapierSdkApps", undefined, undefined, properties),
283
- ]));
284
- }
285
- mapFieldTypeToTypeNode(field) {
286
- // TODO: Handle choices when needed - choices are handled separately through listInputFieldChoices
287
- // Map Zapier field types to TypeScript types
288
- // Handle the new enum types from InputFieldItem.value_type
289
- switch (field.value_type?.toLowerCase()) {
290
- case "string":
291
- case "text":
292
- case "email":
293
- case "url":
294
- case "password":
295
- case "datetime":
296
- case "date":
297
- case "file":
298
- return this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
299
- case "integer":
300
- case "number":
301
- return this.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
302
- case "boolean":
303
- return this.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
304
- case "array":
305
- return this.factory.createArrayTypeNode(this.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword));
306
- case "object":
307
- return this.factory.createTypeReferenceNode("Record", [
308
- this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
309
- this.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
310
- ]);
311
- default:
312
- // Default to string | number | boolean for unknown types
313
- return this.factory.createUnionTypeNode([
314
- this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
315
- this.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
316
- this.factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword),
317
- ]);
318
- }
319
- }
320
- capitalize(str) {
321
- return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
322
- }
323
- sanitizeActionName(actionKey) {
324
- // Ensure the action name is a valid TypeScript identifier
325
- let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
326
- // If it starts with a number, prepend an underscore
327
- if (/^[0-9]/.test(sanitized)) {
328
- sanitized = "_" + sanitized;
329
- }
330
- return sanitized;
331
- }
332
- sanitizeFieldName(fieldKey) {
333
- // Ensure the field name is a valid TypeScript identifier
334
- let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
335
- // If it starts with a number, prepend an underscore
336
- if (/^[0-9]/.test(sanitized)) {
337
- sanitized = "_" + sanitized;
338
- }
339
- return sanitized;
340
- }
341
- escapeComment(comment) {
342
- // Escape comment text to prevent breaking the JSDoc comment
343
- return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
344
- }
345
- createPropertyName(name) {
346
- // Check if the name is a valid JavaScript identifier
347
- if (this.isValidIdentifier(name)) {
348
- return this.factory.createIdentifier(name);
349
- }
350
- else {
351
- // Use string literal for invalid identifiers (e.g., contains dashes)
352
- return this.factory.createStringLiteral(name);
353
- }
354
- }
355
- isValidIdentifier(name) {
356
- // JavaScript identifier rules: must start with letter, $, or _,
357
- // followed by letters, digits, $, or _
358
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
359
- }
360
- getPreferredProgrammaticKey(app) {
361
- // If we have a slug, convert it to snake_case as the preferred programmatic key
362
- if (app.slug) {
363
- const snakeCaseSlug = toSnakeCase(app.slug);
364
- if (this.isValidIdentifier(snakeCaseSlug)) {
365
- return snakeCaseSlug;
366
- }
367
- }
368
- // Otherwise, use the main key if it's a valid identifier
369
- if (this.isValidIdentifier(app.key)) {
370
- return app.key;
371
- }
372
- // Fallback: sanitize the key to make it a valid identifier
373
- return this.sanitizeToIdentifier(app.key);
374
- }
375
- getPreferredAppName(app) {
376
- const preferredKey = this.getPreferredProgrammaticKey(app);
377
- // If it's snake_case, convert to PascalCase
378
- if (preferredKey.includes("_")) {
379
- return preferredKey
380
- .split("_")
381
- .map((word) => this.capitalize(word.toLowerCase()))
382
- .join("");
383
- }
384
- // Otherwise, capitalize first letter for PascalCase
385
- return this.capitalize(preferredKey);
386
- }
387
- sanitizeToIdentifier(name) {
388
- // Convert any string to a valid JavaScript identifier
389
- let sanitized = name.replace(/[^a-zA-Z0-9_$]/g, "_");
390
- // If it starts with a number, prepend an underscore
391
- if (/^[0-9]/.test(sanitized)) {
392
- sanitized = "_" + sanitized;
393
- }
394
- return sanitized;
395
- }
396
- getAllKeys(app) {
397
- // Return all possible keys for this app
398
- const allKeys = new Set([app.key]);
399
- if (app.slug) {
400
- allKeys.add(app.slug);
401
- allKeys.add(toSnakeCase(app.slug));
402
- }
403
- return Array.from(allKeys);
404
- }
405
- }
@@ -1,5 +0,0 @@
1
- export { createZapierCliSdk, type ZapierCliSdkOptions } from "./sdk";
2
- export type { CliEventContext, CliCommandExecutedEventData, } from "./telemetry/builders";
3
- export { buildCliCommandExecutedEvent } from "./telemetry/builders";
4
- export type { CliCommandExecutedEvent } from "./telemetry/events";
5
- export { RESERVED_CLI_OPTIONS, SHARED_COMMAND_CLI_OPTIONS, ReservedCliParameter, getReservedCliOption, } from "./utils/cli-options";
package/dist/src/index.js DELETED
@@ -1,5 +0,0 @@
1
- // Main exports for the CLI package
2
- export { createZapierCliSdk } from "./sdk";
3
- export { buildCliCommandExecutedEvent } from "./telemetry/builders";
4
- // All CLI functionality is now schema-driven via generateCLICommands
5
- export { RESERVED_CLI_OPTIONS, SHARED_COMMAND_CLI_OPTIONS, ReservedCliParameter, getReservedCliOption, } from "./utils/cli-options";
@@ -1,4 +0,0 @@
1
- import Conf from "conf";
2
- export declare const DEFAULT_AUTH_BASE_URL = "https://zapier.com";
3
- export declare function getConfig(): Conf;
4
- export declare function resetConfig(): void;
@@ -1,21 +0,0 @@
1
- import Conf from "conf";
2
- import { existsSync } from "fs";
3
- export const DEFAULT_AUTH_BASE_URL = "https://zapier.com";
4
- let config = null;
5
- export function getConfig() {
6
- if (!config) {
7
- // Conf does not create the file until the first set() call.
8
- config = new Conf({ projectName: "zapier-sdk-cli" });
9
- // If the config file already exists but has no cache mode marker, an older
10
- // SDK version created it. Set the marker to "config" so the login flow will
11
- // prompt the user to upgrade to keychain cache. Otherwise, stamp "keychain"
12
- // so that any future writes to the config don't leave it unmarked.
13
- if (!config.has("login_storage_mode")) {
14
- config.set("login_storage_mode", existsSync(config.path) ? "config" : "keychain");
15
- }
16
- }
17
- return config;
18
- }
19
- export function resetConfig() {
20
- config = null;
21
- }
@@ -1,14 +0,0 @@
1
- import { type ApiClient } from "@zapier/zapier-sdk";
2
- import { type CredentialsEntry } from "./credentials-store";
3
- export type LogoutEventEmitter = (event: {
4
- type: string;
5
- payload: Record<string, unknown>;
6
- timestamp: number;
7
- }) => void;
8
- export declare function emitAuthLogout(onEvent: LogoutEventEmitter | undefined): void;
9
- export declare function revokeCredentials({ api, credentials, onEvent, alwaysClearLocalState, }: {
10
- api: ApiClient;
11
- credentials: CredentialsEntry;
12
- onEvent?: LogoutEventEmitter;
13
- alwaysClearLocalState?: boolean;
14
- }): Promise<void>;
@@ -1,95 +0,0 @@
1
- import { invalidateCachedToken, isPermanentHttpError, } from "@zapier/zapier-sdk";
2
- import { clearLegacyJwtState } from "./legacy-jwt";
3
- import { deleteStoredClientCredentials, } from "./credentials-store";
4
- import { withRetry } from "../utils/retry";
5
- export function emitAuthLogout(onEvent) {
6
- onEvent?.({
7
- type: "auth_logout",
8
- payload: { message: "Logged out successfully", operation: "logout" },
9
- timestamp: Date.now(),
10
- });
11
- }
12
- function getStatusCode(err) {
13
- if (typeof err === "object" && err !== null && "statusCode" in err) {
14
- return err.statusCode;
15
- }
16
- return undefined;
17
- }
18
- const REVOKE_WARNING_TAIL = "Local state will be cleared, but the credential may still be active. " +
19
- "Verify or revoke via `list-client-credentials` or `delete-client-credentials`.";
20
- // Shown only when `logout` tears down local state after the server *rejected*
21
- // revocation (a permanent 4xx). Retrying won't help, and `list-`/`delete-client-
22
- // credentials` would hit the same refusal until the user re-authenticates — so we
23
- // send them through `login`, which restores the ability to manage credentials.
24
- const REVOKE_REJECTED_WARNING = "Could not revoke the credential on the server: the request was rejected " +
25
- "(your current credentials may lack permission to revoke it). Local state has " +
26
- "been cleared, but the credential may still be active on the server — run " +
27
- "`login` to re-authenticate, then `delete-client-credentials` to remove it.";
28
- // Re-login flows pass no emitter so credential rotation stays silent.
29
- export async function revokeCredentials({ api, credentials, onEvent, alwaysClearLocalState = false, }) {
30
- try {
31
- await withRetry({
32
- // Permanent errors (403/400) won't change on retry — fail fast instead of
33
- // burning the backoff budget. The outer catch then rethrows (re-login) or
34
- // swallows and clears local state (logout) per `alwaysClearLocalState`.
35
- shouldRetry: (err) => !isPermanentHttpError(err),
36
- action: async () => {
37
- try {
38
- await api.delete(`/api/v0/client-credentials/${credentials.clientId}`, undefined, { authRequired: true, requiredScopes: ["credentials"] });
39
- }
40
- catch (err) {
41
- const status = getStatusCode(err);
42
- if (status === 404)
43
- return;
44
- if (status === 401) {
45
- console.warn("Could not revoke credentials on the server (unauthorized). " +
46
- REVOKE_WARNING_TAIL);
47
- return;
48
- }
49
- throw err;
50
- }
51
- },
52
- });
53
- }
54
- catch (err) {
55
- // Re-login leaves `alwaysClearLocalState` false because it wants the throw:
56
- // any revoke failure (permanent OR transient) must surface so it can confirm
57
- // before replacing creds (see `account-auth.ts`). Only `logout` sets the flag
58
- // — it is teardown, so it swallows the failure and clears local state rather
59
- // than strand the user behind a revoke they can never complete.
60
- if (!alwaysClearLocalState)
61
- throw err;
62
- if (isPermanentHttpError(err)) {
63
- // A permanent client rejection (4xx except the 401/404 the action handles
64
- // above — e.g. a 403 when the token lacks the `credentials` scope) is the
65
- // server's definitive "you may not revoke this". Retrying won't help, and
66
- // there's no dashboard fallback; `delete-client-credentials` needs the same
67
- // refused `credentials` scope, so the message routes the user through `login`
68
- // (which restores that scope) first, then `delete-client-credentials`.
69
- console.warn(REVOKE_REJECTED_WARNING);
70
- }
71
- else {
72
- // Transient 5xx/429, a network failure, or an auth-resolution throw that
73
- // never built the request (e.g. a missing keychain secret): revocation never
74
- // reached a verdict, so a later `delete-client-credentials` could still
75
- // succeed once things recover.
76
- console.warn("Could not revoke credentials on the server. " + REVOKE_WARNING_TAIL);
77
- }
78
- }
79
- try {
80
- await deleteStoredClientCredentials({
81
- name: credentials.name,
82
- baseUrl: credentials.baseUrl,
83
- });
84
- }
85
- catch (err) {
86
- console.warn("[revokeCredentials] Local store cleanup failed:", err);
87
- }
88
- await clearLegacyJwtState();
89
- await invalidateCachedToken({
90
- clientId: credentials.clientId,
91
- scopes: credentials.scopes,
92
- baseUrl: credentials.baseUrl,
93
- });
94
- emitAuthLogout(onEvent);
95
- }
@@ -1,60 +0,0 @@
1
- import type { ClientCredentialsObject } from "@zapier/zapier-sdk";
2
- import { z } from "zod";
3
- declare const CredentialsEntrySchema: z.ZodObject<{
4
- name: z.ZodString;
5
- clientId: z.ZodString;
6
- createdAt: z.ZodNumber;
7
- scopes: z.ZodArray<z.ZodString>;
8
- baseUrl: z.ZodString;
9
- }, z.core.$strip>;
10
- export type CredentialsEntry = z.infer<typeof CredentialsEntrySchema>;
11
- export declare function getActiveCredentials(options?: {
12
- baseUrl?: string;
13
- }): CredentialsEntry | undefined;
14
- /**
15
- * Pick the first credential name not already present in `taken`. Returns
16
- * `baseName` if it is free, otherwise appends an incrementing `-1`, `-2`, …
17
- * suffix to the literal base — a base ending in a digit is left intact, so
18
- * `acme-1` collides into `acme-1-1`. Storing a credential under a name that
19
- * already exists locally silently replaces that entry (and deletes its
20
- * keychain secret), so non-interactive login uses this to avoid clobbering a
21
- * dormant credential of the same name.
22
- */
23
- export declare function firstAvailableCredentialName({ baseName, taken, }: {
24
- baseName: string;
25
- taken: ReadonlySet<string>;
26
- }): string;
27
- /**
28
- * Resolve a locally-unique credential name for the given baseUrl. Local
29
- * credentials are keyed by (name, baseUrl), so name collisions — and the
30
- * suffixing that avoids them — are scoped per baseUrl.
31
- */
32
- export declare function resolveAvailableCredentialName({ baseName, baseUrl, }: {
33
- baseName: string;
34
- baseUrl?: string;
35
- }): string;
36
- /**
37
- * Whether a credential with this exact (name, baseUrl) is already stored
38
- * locally. Used to reject an explicitly-supplied login name that would
39
- * otherwise silently overwrite a dormant credential of the same name.
40
- */
41
- export declare function credentialNameExists({ name, baseUrl, }: {
42
- name: string;
43
- baseUrl?: string;
44
- }): boolean;
45
- export declare function storeClientCredentials({ name, clientId, clientSecret, scopes, baseUrl, }: {
46
- name: string;
47
- clientId: string;
48
- clientSecret: string;
49
- scopes: string[];
50
- baseUrl?: string;
51
- }): Promise<void>;
52
- export declare function getStoredClientCredentials(options?: {
53
- name?: string;
54
- baseUrl?: string;
55
- }): Promise<ClientCredentialsObject | undefined>;
56
- export declare function deleteStoredClientCredentials({ name, baseUrl, }: {
57
- name: string;
58
- baseUrl?: string;
59
- }): Promise<void>;
60
- export {};