@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.
- package/CHANGELOG.md +32 -0
- package/README.md +35 -51
- package/dist/cli.cjs +950 -433
- package/dist/cli.mjs +951 -434
- package/dist/index.cjs +729 -336
- package/dist/index.mjs +730 -337
- package/dist/package.json +1 -1
- package/dist/src/plugins/add/ast-generator.d.ts +37 -0
- package/dist/src/plugins/add/ast-generator.js +403 -0
- package/dist/src/plugins/add/index.d.ts +13 -0
- package/dist/src/plugins/add/index.js +120 -0
- package/dist/src/plugins/add/schemas.d.ts +18 -0
- package/dist/src/plugins/add/schemas.js +19 -0
- package/dist/src/plugins/getLoginConfigPath/index.d.ts +15 -0
- package/dist/src/plugins/getLoginConfigPath/index.js +19 -0
- package/dist/src/plugins/getLoginConfigPath/schemas.d.ts +3 -0
- package/dist/src/plugins/getLoginConfigPath/schemas.js +5 -0
- package/dist/src/plugins/index.d.ts +2 -2
- package/dist/src/plugins/index.js +2 -2
- package/dist/src/sdk.js +3 -3
- package/dist/src/utils/cli-generator-utils.d.ts +2 -1
- package/dist/src/utils/cli-generator-utils.js +11 -5
- package/dist/src/utils/cli-generator.js +65 -65
- package/dist/src/utils/parameter-resolver.d.ts +4 -1
- package/dist/src/utils/parameter-resolver.js +92 -15
- package/dist/src/utils/schema-formatter.d.ts +5 -1
- package/dist/src/utils/schema-formatter.js +48 -18
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/plugins/add/ast-generator.ts +777 -0
- package/src/plugins/add/index.test.ts +58 -0
- package/src/plugins/add/index.ts +187 -0
- package/src/plugins/add/schemas.ts +26 -0
- package/src/plugins/getLoginConfigPath/index.ts +45 -0
- package/src/plugins/getLoginConfigPath/schemas.ts +10 -0
- package/src/plugins/index.ts +2 -2
- package/src/sdk.ts +4 -4
- package/src/utils/cli-generator-utils.ts +17 -5
- package/src/utils/cli-generator.ts +90 -79
- package/src/utils/parameter-resolver.ts +155 -21
- package/src/utils/schema-formatter.ts +68 -33
- package/tsup.config.ts +1 -1
- package/dist/src/plugins/generateTypes/index.d.ts +0 -21
- package/dist/src/plugins/generateTypes/index.js +0 -312
- package/dist/src/plugins/generateTypes/schemas.d.ts +0 -18
- package/dist/src/plugins/generateTypes/schemas.js +0 -14
- package/dist/src/plugins/getConfigPath/index.d.ts +0 -15
- package/dist/src/plugins/getConfigPath/index.js +0 -19
- package/dist/src/plugins/getConfigPath/schemas.d.ts +0 -3
- package/dist/src/plugins/getConfigPath/schemas.js +0 -5
- package/src/plugins/generateTypes/index.ts +0 -444
- package/src/plugins/generateTypes/schemas.ts +0 -23
- package/src/plugins/getConfigPath/index.ts +0 -42
- package/src/plugins/getConfigPath/schemas.ts +0 -8
package/dist/index.cjs
CHANGED
|
@@ -10,9 +10,11 @@ var chalk = require('chalk');
|
|
|
10
10
|
var zapierSdkCliLogin = require('@zapier/zapier-sdk-cli-login');
|
|
11
11
|
var zod = require('zod');
|
|
12
12
|
var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
|
|
13
|
+
var esbuild = require('esbuild');
|
|
13
14
|
var fs = require('fs');
|
|
14
15
|
var path = require('path');
|
|
15
|
-
var
|
|
16
|
+
var ts = require('typescript');
|
|
17
|
+
var promises = require('fs/promises');
|
|
16
18
|
|
|
17
19
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
20
|
|
|
@@ -42,6 +44,7 @@ var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
|
42
44
|
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
43
45
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
44
46
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
47
|
+
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
45
48
|
|
|
46
49
|
// src/sdk.ts
|
|
47
50
|
|
|
@@ -109,28 +112,28 @@ var client_default = api;
|
|
|
109
112
|
|
|
110
113
|
// src/utils/getCallablePromise.ts
|
|
111
114
|
var getCallablePromise = () => {
|
|
112
|
-
let
|
|
115
|
+
let resolve3 = () => {
|
|
113
116
|
};
|
|
114
117
|
let reject = () => {
|
|
115
118
|
};
|
|
116
119
|
const promise = new Promise((_resolve, _reject) => {
|
|
117
|
-
|
|
120
|
+
resolve3 = _resolve;
|
|
118
121
|
reject = _reject;
|
|
119
122
|
});
|
|
120
123
|
return {
|
|
121
124
|
promise,
|
|
122
|
-
resolve:
|
|
125
|
+
resolve: resolve3,
|
|
123
126
|
reject
|
|
124
127
|
};
|
|
125
128
|
};
|
|
126
129
|
var getCallablePromise_default = getCallablePromise;
|
|
127
130
|
var findAvailablePort = () => {
|
|
128
|
-
return new Promise((
|
|
131
|
+
return new Promise((resolve3, reject) => {
|
|
129
132
|
let portIndex = 0;
|
|
130
133
|
const tryPort = (port) => {
|
|
131
134
|
const server = express__default.default().listen(port, () => {
|
|
132
135
|
server.close();
|
|
133
|
-
|
|
136
|
+
resolve3(port);
|
|
134
137
|
});
|
|
135
138
|
server.on("error", (err) => {
|
|
136
139
|
if (err.code === "EADDRINUSE") {
|
|
@@ -220,15 +223,15 @@ var login = async (timeoutMs = LOGIN_TIMEOUT_MS) => {
|
|
|
220
223
|
} finally {
|
|
221
224
|
process.off("SIGINT", cleanup);
|
|
222
225
|
process.off("SIGTERM", cleanup);
|
|
223
|
-
await new Promise((
|
|
226
|
+
await new Promise((resolve3) => {
|
|
224
227
|
const timeout = setTimeout(() => {
|
|
225
228
|
log_default.info("Server close timed out, forcing connection shutdown...");
|
|
226
229
|
connections.forEach((conn) => conn.destroy());
|
|
227
|
-
|
|
230
|
+
resolve3();
|
|
228
231
|
}, 1e3);
|
|
229
232
|
server.close(() => {
|
|
230
233
|
clearTimeout(timeout);
|
|
231
|
-
|
|
234
|
+
resolve3();
|
|
232
235
|
});
|
|
233
236
|
});
|
|
234
237
|
}
|
|
@@ -323,323 +326,6 @@ var mcpPlugin = ({ context }) => {
|
|
|
323
326
|
}
|
|
324
327
|
};
|
|
325
328
|
};
|
|
326
|
-
var GenerateTypesSchema = zod.z.object({
|
|
327
|
-
appKey: zapierSdk.AppKeyPropertySchema.describe("App key to generate SDK code for"),
|
|
328
|
-
authenticationId: zapierSdk.AuthenticationIdPropertySchema.optional(),
|
|
329
|
-
output: zapierSdk.OutputPropertySchema.optional().describe(
|
|
330
|
-
"Output file path (defaults to generated/<appKey>.ts)"
|
|
331
|
-
),
|
|
332
|
-
lockFilePath: zod.z.string().optional().describe("Path to the .zapierrc lock file (defaults to .zapierrc)")
|
|
333
|
-
}).describe("Generate TypeScript SDK code for a specific app");
|
|
334
|
-
var generateTypesPlugin = ({ sdk }) => {
|
|
335
|
-
const generateTypesWithSdk = zapierSdk.createFunction(
|
|
336
|
-
async function generateTypesWithSdk2(options) {
|
|
337
|
-
return await generateTypes({ ...options, sdk });
|
|
338
|
-
},
|
|
339
|
-
GenerateTypesSchema
|
|
340
|
-
);
|
|
341
|
-
return {
|
|
342
|
-
generateTypes: generateTypesWithSdk,
|
|
343
|
-
context: {
|
|
344
|
-
meta: {
|
|
345
|
-
generateTypes: {
|
|
346
|
-
categories: ["utility"],
|
|
347
|
-
inputSchema: GenerateTypesSchema
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
};
|
|
353
|
-
function generateFetchMethodSignature() {
|
|
354
|
-
return ` /** Make authenticated HTTP requests through Zapier's Relay service */
|
|
355
|
-
fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
|
|
356
|
-
}
|
|
357
|
-
async function generateTypes(options) {
|
|
358
|
-
const {
|
|
359
|
-
appKey,
|
|
360
|
-
authenticationId,
|
|
361
|
-
output = `./types/${appKey}.d.ts`,
|
|
362
|
-
sdk
|
|
363
|
-
} = options;
|
|
364
|
-
const { app, version } = parseAppIdentifier(appKey);
|
|
365
|
-
const actionsResult = await sdk.listActions({
|
|
366
|
-
appKey: app
|
|
367
|
-
});
|
|
368
|
-
const actions = actionsResult.data;
|
|
369
|
-
if (actions.length === 0) {
|
|
370
|
-
const typeDefinitions2 = generateEmptyTypesFile(app, version);
|
|
371
|
-
if (output) {
|
|
372
|
-
fs__namespace.mkdirSync(path__namespace.dirname(output), { recursive: true });
|
|
373
|
-
fs__namespace.writeFileSync(output, typeDefinitions2, "utf8");
|
|
374
|
-
}
|
|
375
|
-
return typeDefinitions2;
|
|
376
|
-
}
|
|
377
|
-
const actionsWithFields = [];
|
|
378
|
-
if (authenticationId) {
|
|
379
|
-
for (const action of actions) {
|
|
380
|
-
try {
|
|
381
|
-
const manifestEntry = sdk.getContext().getManifestEntry(appKey);
|
|
382
|
-
const fieldsResult = await sdk.listInputFields({
|
|
383
|
-
// 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
|
|
384
|
-
appKey: manifestEntry ? appKey : action.app_key,
|
|
385
|
-
actionKey: action.key,
|
|
386
|
-
actionType: action.action_type,
|
|
387
|
-
authenticationId
|
|
388
|
-
});
|
|
389
|
-
const fields = fieldsResult.data.map((field) => {
|
|
390
|
-
const fieldObj = field;
|
|
391
|
-
return {
|
|
392
|
-
...fieldObj,
|
|
393
|
-
required: fieldObj.is_required || fieldObj.required || false
|
|
394
|
-
};
|
|
395
|
-
});
|
|
396
|
-
actionsWithFields.push({
|
|
397
|
-
...action,
|
|
398
|
-
inputFields: fields,
|
|
399
|
-
name: action.title || action.key
|
|
400
|
-
});
|
|
401
|
-
} catch {
|
|
402
|
-
actionsWithFields.push({
|
|
403
|
-
...action,
|
|
404
|
-
inputFields: [],
|
|
405
|
-
name: action.title || action.key
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
} else {
|
|
410
|
-
actions.forEach((action) => {
|
|
411
|
-
actionsWithFields.push({
|
|
412
|
-
...action,
|
|
413
|
-
inputFields: [],
|
|
414
|
-
name: action.title || action.key
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
const typeDefinitions = generateTypeDefinitions(
|
|
419
|
-
app,
|
|
420
|
-
actionsWithFields,
|
|
421
|
-
version
|
|
422
|
-
);
|
|
423
|
-
if (output) {
|
|
424
|
-
fs__namespace.mkdirSync(path__namespace.dirname(output), { recursive: true });
|
|
425
|
-
fs__namespace.writeFileSync(output, typeDefinitions, "utf8");
|
|
426
|
-
}
|
|
427
|
-
return typeDefinitions;
|
|
428
|
-
}
|
|
429
|
-
function parseAppIdentifier(identifier) {
|
|
430
|
-
const parts = identifier.split("@");
|
|
431
|
-
return {
|
|
432
|
-
app: parts[0],
|
|
433
|
-
version: parts[1]
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
function generateTypeDefinitions(appKey, actions, version) {
|
|
437
|
-
if (actions.length === 0) {
|
|
438
|
-
return generateEmptyTypesFile(appKey, version);
|
|
439
|
-
}
|
|
440
|
-
const actionsByType = actions.reduce(
|
|
441
|
-
(acc, action) => {
|
|
442
|
-
if (!acc[action.action_type]) {
|
|
443
|
-
acc[action.action_type] = [];
|
|
444
|
-
}
|
|
445
|
-
acc[action.action_type].push(action);
|
|
446
|
-
return acc;
|
|
447
|
-
},
|
|
448
|
-
{}
|
|
449
|
-
);
|
|
450
|
-
const appName = capitalize(appKey);
|
|
451
|
-
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
452
|
-
let output = `/* eslint-disable @typescript-eslint/naming-convention */
|
|
453
|
-
/**
|
|
454
|
-
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
455
|
-
${versionComment}
|
|
456
|
-
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
457
|
-
*
|
|
458
|
-
* Usage:
|
|
459
|
-
* import type { ${appName}Sdk } from './path/to/this/file'
|
|
460
|
-
* const sdk = createZapierSdk() as unknown as ${appName}Sdk
|
|
461
|
-
*
|
|
462
|
-
* // Direct usage (per-call auth):
|
|
463
|
-
* await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
|
|
464
|
-
*
|
|
465
|
-
* // Factory usage (pinned auth):
|
|
466
|
-
* const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
|
|
467
|
-
* await my${appName}.search.user_by_email({ inputs: { email } })
|
|
468
|
-
*/
|
|
469
|
-
|
|
470
|
-
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
471
|
-
import { z } from 'zod'
|
|
472
|
-
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
473
|
-
|
|
474
|
-
`;
|
|
475
|
-
actions.forEach((action) => {
|
|
476
|
-
if (action.inputFields.length > 0) {
|
|
477
|
-
const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
|
|
478
|
-
sanitizeActionName(action.key)
|
|
479
|
-
)}Inputs`;
|
|
480
|
-
output += `interface ${inputTypeName} {
|
|
481
|
-
`;
|
|
482
|
-
action.inputFields.forEach((field) => {
|
|
483
|
-
const isOptional = !field.required;
|
|
484
|
-
const fieldType = mapFieldTypeToTypeScript(field);
|
|
485
|
-
const description = field.helpText ? ` /** ${escapeComment(field.helpText)} */
|
|
486
|
-
` : "";
|
|
487
|
-
output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}
|
|
488
|
-
`;
|
|
489
|
-
});
|
|
490
|
-
output += `}
|
|
491
|
-
|
|
492
|
-
`;
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
|
|
496
|
-
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
497
|
-
output += `interface ${typeName} {
|
|
498
|
-
`;
|
|
499
|
-
typeActions.forEach((action) => {
|
|
500
|
-
const actionName = sanitizeActionName(action.key);
|
|
501
|
-
const description = action.description ? ` /** ${escapeComment(action.description)} */
|
|
502
|
-
` : "";
|
|
503
|
-
if (action.inputFields.length > 0) {
|
|
504
|
-
const inputTypeName = `${appName}${capitalize(action.action_type)}${capitalize(
|
|
505
|
-
sanitizeActionName(action.key)
|
|
506
|
-
)}Inputs`;
|
|
507
|
-
output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>
|
|
508
|
-
`;
|
|
509
|
-
} else {
|
|
510
|
-
output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>
|
|
511
|
-
`;
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
output += `}
|
|
515
|
-
|
|
516
|
-
`;
|
|
517
|
-
});
|
|
518
|
-
output += `interface ${appName}AppProxy {
|
|
519
|
-
`;
|
|
520
|
-
Object.keys(actionsByType).forEach((actionType) => {
|
|
521
|
-
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
522
|
-
output += ` ${actionType}: ${typeName}
|
|
523
|
-
`;
|
|
524
|
-
});
|
|
525
|
-
output += generateFetchMethodSignature() + "\n";
|
|
526
|
-
output += `}
|
|
527
|
-
|
|
528
|
-
`;
|
|
529
|
-
output += `interface ${appName}AppFactory {
|
|
530
|
-
`;
|
|
531
|
-
output += ` (options: { authenticationId: number }): ${appName}AppProxy
|
|
532
|
-
`;
|
|
533
|
-
output += `}
|
|
534
|
-
|
|
535
|
-
`;
|
|
536
|
-
output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
537
|
-
|
|
538
|
-
`;
|
|
539
|
-
output += `export interface ${appName}Sdk {
|
|
540
|
-
`;
|
|
541
|
-
output += ` apps: {
|
|
542
|
-
`;
|
|
543
|
-
output += ` ${appKey}: ${appName}AppWithFactory
|
|
544
|
-
`;
|
|
545
|
-
output += ` }
|
|
546
|
-
`;
|
|
547
|
-
output += `}
|
|
548
|
-
`;
|
|
549
|
-
return output;
|
|
550
|
-
}
|
|
551
|
-
function generateEmptyTypesFile(appKey, version) {
|
|
552
|
-
const appName = capitalize(appKey);
|
|
553
|
-
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
554
|
-
return `/* eslint-disable @typescript-eslint/naming-convention */
|
|
555
|
-
/**
|
|
556
|
-
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
557
|
-
${versionComment}
|
|
558
|
-
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
559
|
-
*
|
|
560
|
-
* No actions found for this app.
|
|
561
|
-
*/
|
|
562
|
-
|
|
563
|
-
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
564
|
-
import { z } from 'zod'
|
|
565
|
-
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
566
|
-
|
|
567
|
-
interface ${appName}AppProxy {
|
|
568
|
-
// No actions available
|
|
569
|
-
${generateFetchMethodSignature()}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
interface ${appName}AppFactory {
|
|
573
|
-
(options: { authenticationId: number }): ${appName}AppProxy
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
577
|
-
|
|
578
|
-
export interface ${appName}Sdk {
|
|
579
|
-
apps: {
|
|
580
|
-
${appKey}: ${appName}AppWithFactory
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
`;
|
|
584
|
-
}
|
|
585
|
-
function capitalize(str) {
|
|
586
|
-
return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
|
|
587
|
-
}
|
|
588
|
-
function sanitizeActionName(actionKey) {
|
|
589
|
-
let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
590
|
-
if (/^[0-9]/.test(sanitized)) {
|
|
591
|
-
sanitized = "_" + sanitized;
|
|
592
|
-
}
|
|
593
|
-
return sanitized;
|
|
594
|
-
}
|
|
595
|
-
function sanitizeFieldName(fieldKey) {
|
|
596
|
-
let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
597
|
-
if (/^[0-9]/.test(sanitized)) {
|
|
598
|
-
sanitized = "_" + sanitized;
|
|
599
|
-
}
|
|
600
|
-
return sanitized;
|
|
601
|
-
}
|
|
602
|
-
function escapeComment(comment) {
|
|
603
|
-
return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
604
|
-
}
|
|
605
|
-
function mapFieldTypeToTypeScript(field) {
|
|
606
|
-
if (field.choices && field.choices.length > 0) {
|
|
607
|
-
const choiceValues = field.choices.filter(
|
|
608
|
-
(choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
|
|
609
|
-
).map(
|
|
610
|
-
(choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value
|
|
611
|
-
);
|
|
612
|
-
if (choiceValues.length > 0) {
|
|
613
|
-
return choiceValues.join(" | ");
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
switch (field.type?.toLowerCase()) {
|
|
617
|
-
case "string":
|
|
618
|
-
case "text":
|
|
619
|
-
case "email":
|
|
620
|
-
case "url":
|
|
621
|
-
case "password":
|
|
622
|
-
return "string";
|
|
623
|
-
case "integer":
|
|
624
|
-
case "number":
|
|
625
|
-
return "number";
|
|
626
|
-
case "boolean":
|
|
627
|
-
return "boolean";
|
|
628
|
-
case "datetime":
|
|
629
|
-
case "date":
|
|
630
|
-
return "string";
|
|
631
|
-
// ISO date strings
|
|
632
|
-
case "file":
|
|
633
|
-
return "string";
|
|
634
|
-
// File URL or content
|
|
635
|
-
case "array":
|
|
636
|
-
return "any[]";
|
|
637
|
-
case "object":
|
|
638
|
-
return "Record<string, any>";
|
|
639
|
-
default:
|
|
640
|
-
return "string | number | boolean";
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
329
|
var BundleCodeSchema = zod.z.object({
|
|
644
330
|
input: zod.z.string().min(1).describe("Input TypeScript file path to bundle"),
|
|
645
331
|
output: zapierSdk.OutputPropertySchema.optional().describe(
|
|
@@ -731,21 +417,728 @@ async function bundleCode(options) {
|
|
|
731
417
|
);
|
|
732
418
|
}
|
|
733
419
|
}
|
|
734
|
-
var
|
|
735
|
-
var
|
|
736
|
-
const
|
|
737
|
-
async function
|
|
420
|
+
var GetLoginConfigPathSchema = zod.z.object({}).describe("Show the path to the login configuration file");
|
|
421
|
+
var getLoginConfigPathPlugin = () => {
|
|
422
|
+
const getLoginConfigPathWithSdk = zapierSdk.createFunction(
|
|
423
|
+
async function getLoginConfigPathWithSdk2(_options) {
|
|
738
424
|
return zapierSdkCliLogin.getConfigPath();
|
|
739
425
|
},
|
|
740
|
-
|
|
426
|
+
GetLoginConfigPathSchema
|
|
741
427
|
);
|
|
742
428
|
return {
|
|
743
|
-
|
|
429
|
+
getLoginConfigPath: getLoginConfigPathWithSdk,
|
|
430
|
+
context: {
|
|
431
|
+
meta: {
|
|
432
|
+
getLoginConfigPath: {
|
|
433
|
+
categories: ["utility"],
|
|
434
|
+
inputSchema: GetLoginConfigPathSchema
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
};
|
|
440
|
+
var AddSchema = zod.z.object({
|
|
441
|
+
appKeys: zod.z.array(zod.z.string().min(1, "App key cannot be empty")).min(1, "At least one app key is required"),
|
|
442
|
+
authenticationIds: zod.z.array(zod.z.string()).optional().describe("Authentication IDs to use for type generation"),
|
|
443
|
+
configPath: zod.z.string().optional().describe(
|
|
444
|
+
`Path to Zapier config file (defaults to '${zapierSdk.DEFAULT_CONFIG_PATH}')`
|
|
445
|
+
),
|
|
446
|
+
typesOutput: zod.z.string().optional().describe(
|
|
447
|
+
"Directory for TypeScript type files (defaults to (src|lib|.)/zapier/apps/)"
|
|
448
|
+
)
|
|
449
|
+
});
|
|
450
|
+
var AstTypeGenerator = class {
|
|
451
|
+
constructor() {
|
|
452
|
+
this.factory = ts__namespace.factory;
|
|
453
|
+
this.printer = ts__namespace.createPrinter({
|
|
454
|
+
newLine: ts__namespace.NewLineKind.LineFeed,
|
|
455
|
+
removeComments: false,
|
|
456
|
+
omitTrailingSemicolon: false
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Generate TypeScript types using AST for a specific app
|
|
461
|
+
*/
|
|
462
|
+
async generateTypes(options) {
|
|
463
|
+
const { appKey, authenticationId, sdk } = options;
|
|
464
|
+
const { app, version } = this.parseAppIdentifier(appKey);
|
|
465
|
+
const actionsResult = await sdk.listActions({
|
|
466
|
+
appKey: app
|
|
467
|
+
});
|
|
468
|
+
const actions = actionsResult.data;
|
|
469
|
+
if (actions.length === 0) {
|
|
470
|
+
return this.generateEmptyTypesFile(app, version);
|
|
471
|
+
}
|
|
472
|
+
const actionsWithFields = [];
|
|
473
|
+
if (authenticationId) {
|
|
474
|
+
for (const action of actions) {
|
|
475
|
+
try {
|
|
476
|
+
const fieldsResult = await sdk.listInputFields({
|
|
477
|
+
appKey,
|
|
478
|
+
actionKey: action.key,
|
|
479
|
+
actionType: action.action_type,
|
|
480
|
+
authenticationId
|
|
481
|
+
});
|
|
482
|
+
const fields = fieldsResult.data.map(
|
|
483
|
+
(field) => {
|
|
484
|
+
const fieldObj = field;
|
|
485
|
+
return {
|
|
486
|
+
...fieldObj,
|
|
487
|
+
required: fieldObj.is_required || fieldObj.required || false
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
);
|
|
491
|
+
actionsWithFields.push({
|
|
492
|
+
...action,
|
|
493
|
+
inputFields: fields,
|
|
494
|
+
name: action.title || action.key
|
|
495
|
+
});
|
|
496
|
+
} catch {
|
|
497
|
+
actionsWithFields.push({
|
|
498
|
+
...action,
|
|
499
|
+
inputFields: [],
|
|
500
|
+
name: action.title || action.key
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
} else {
|
|
505
|
+
actions.forEach(
|
|
506
|
+
(action) => {
|
|
507
|
+
actionsWithFields.push({
|
|
508
|
+
...action,
|
|
509
|
+
inputFields: [],
|
|
510
|
+
name: action.title || action.key,
|
|
511
|
+
app_key: action.app_key || appKey,
|
|
512
|
+
action_type: action.action_type || "write",
|
|
513
|
+
title: action.title || action.key,
|
|
514
|
+
type: "action",
|
|
515
|
+
description: action.description || ""
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
const sourceFile = this.createSourceFile(app, actionsWithFields, version);
|
|
521
|
+
return this.printer.printFile(sourceFile);
|
|
522
|
+
}
|
|
523
|
+
parseAppIdentifier(identifier) {
|
|
524
|
+
const parts = identifier.split("@");
|
|
525
|
+
return {
|
|
526
|
+
app: parts[0],
|
|
527
|
+
version: parts[1]
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
createSourceFile(appKey, actions, version) {
|
|
531
|
+
const appName = this.capitalize(appKey);
|
|
532
|
+
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
533
|
+
const headerComment = `Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
534
|
+
${versionComment.slice(3)}
|
|
535
|
+
Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
536
|
+
|
|
537
|
+
This file automatically augments the base SDK types when present.
|
|
538
|
+
No manual imports or type casting required.
|
|
539
|
+
|
|
540
|
+
Usage:
|
|
541
|
+
import { createZapierSdk } from "@zapier/zapier-sdk";
|
|
542
|
+
|
|
543
|
+
const zapier = createZapierSdk();
|
|
544
|
+
// Types are automatically available:
|
|
545
|
+
await zapier.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
|
|
546
|
+
|
|
547
|
+
// Factory usage (pinned auth):
|
|
548
|
+
const my${appName} = zapier.apps.${appKey}({ authenticationId: 123 })
|
|
549
|
+
await my${appName}.search.user_by_email({ inputs: { email } })`;
|
|
550
|
+
const statements = [
|
|
551
|
+
// Import the SDK to activate module augmentation
|
|
552
|
+
this.createImportStatement(["@zapier/zapier-sdk"]),
|
|
553
|
+
// Import types we'll use
|
|
554
|
+
this.createTypeImportStatement(
|
|
555
|
+
[
|
|
556
|
+
"ActionExecutionOptions",
|
|
557
|
+
"ActionExecutionResult",
|
|
558
|
+
"ZapierFetchInitOptions"
|
|
559
|
+
],
|
|
560
|
+
"@zapier/zapier-sdk"
|
|
561
|
+
)
|
|
562
|
+
];
|
|
563
|
+
const actionsByType = this.groupActionsByType(actions);
|
|
564
|
+
actions.forEach((action) => {
|
|
565
|
+
if (action.inputFields.length > 0) {
|
|
566
|
+
const inputInterface = this.createInputInterface(appName, action);
|
|
567
|
+
statements.push(inputInterface);
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
|
|
571
|
+
const actionInterface = this.createActionInterface(
|
|
572
|
+
appName,
|
|
573
|
+
actionType,
|
|
574
|
+
typeActions
|
|
575
|
+
);
|
|
576
|
+
statements.push(actionInterface);
|
|
577
|
+
});
|
|
578
|
+
const appProxyInterface = this.createAppProxyInterface(
|
|
579
|
+
appName,
|
|
580
|
+
actionsByType
|
|
581
|
+
);
|
|
582
|
+
statements.push(appProxyInterface);
|
|
583
|
+
const appFactoryInterface = this.createAppFactoryInterface(appName);
|
|
584
|
+
statements.push(appFactoryInterface);
|
|
585
|
+
const appWithFactoryType = this.createAppWithFactoryType(appName);
|
|
586
|
+
statements.push(appWithFactoryType);
|
|
587
|
+
const moduleAugmentation = this.createModuleAugmentation(appKey, appName);
|
|
588
|
+
statements.push(moduleAugmentation);
|
|
589
|
+
statements.push(
|
|
590
|
+
this.factory.createExportDeclaration(
|
|
591
|
+
void 0,
|
|
592
|
+
false,
|
|
593
|
+
this.factory.createNamedExports([])
|
|
594
|
+
)
|
|
595
|
+
);
|
|
596
|
+
const sourceFile = ts__namespace.createSourceFile(
|
|
597
|
+
"generated.d.ts",
|
|
598
|
+
"",
|
|
599
|
+
ts__namespace.ScriptTarget.Latest,
|
|
600
|
+
false,
|
|
601
|
+
ts__namespace.ScriptKind.TS
|
|
602
|
+
);
|
|
603
|
+
if (statements.length > 0) {
|
|
604
|
+
ts__namespace.addSyntheticLeadingComment(
|
|
605
|
+
statements[0],
|
|
606
|
+
ts__namespace.SyntaxKind.MultiLineCommentTrivia,
|
|
607
|
+
" eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any ",
|
|
608
|
+
true
|
|
609
|
+
);
|
|
610
|
+
ts__namespace.addSyntheticLeadingComment(
|
|
611
|
+
statements[0],
|
|
612
|
+
ts__namespace.SyntaxKind.MultiLineCommentTrivia,
|
|
613
|
+
headerComment,
|
|
614
|
+
true
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
return this.factory.updateSourceFile(sourceFile, statements);
|
|
618
|
+
}
|
|
619
|
+
createImportStatement(imports, from) {
|
|
620
|
+
if (imports.length === 1 && !from && imports[0].startsWith("@")) {
|
|
621
|
+
return this.factory.createImportDeclaration(
|
|
622
|
+
void 0,
|
|
623
|
+
void 0,
|
|
624
|
+
this.factory.createStringLiteral(imports[0]),
|
|
625
|
+
void 0
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
const fromModule = from || imports[0];
|
|
629
|
+
const importNames = from ? imports : [];
|
|
630
|
+
return this.factory.createImportDeclaration(
|
|
631
|
+
void 0,
|
|
632
|
+
importNames.length > 0 ? this.factory.createImportClause(
|
|
633
|
+
false,
|
|
634
|
+
void 0,
|
|
635
|
+
this.factory.createNamedImports(
|
|
636
|
+
importNames.map(
|
|
637
|
+
(name) => this.factory.createImportSpecifier(
|
|
638
|
+
false,
|
|
639
|
+
void 0,
|
|
640
|
+
this.factory.createIdentifier(name)
|
|
641
|
+
)
|
|
642
|
+
)
|
|
643
|
+
)
|
|
644
|
+
) : void 0,
|
|
645
|
+
this.factory.createStringLiteral(fromModule),
|
|
646
|
+
void 0
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
createTypeImportStatement(imports, from) {
|
|
650
|
+
return this.factory.createImportDeclaration(
|
|
651
|
+
void 0,
|
|
652
|
+
this.factory.createImportClause(
|
|
653
|
+
true,
|
|
654
|
+
// typeOnly: true
|
|
655
|
+
void 0,
|
|
656
|
+
this.factory.createNamedImports(
|
|
657
|
+
imports.map(
|
|
658
|
+
(name) => this.factory.createImportSpecifier(
|
|
659
|
+
false,
|
|
660
|
+
void 0,
|
|
661
|
+
this.factory.createIdentifier(name)
|
|
662
|
+
)
|
|
663
|
+
)
|
|
664
|
+
)
|
|
665
|
+
),
|
|
666
|
+
this.factory.createStringLiteral(from),
|
|
667
|
+
void 0
|
|
668
|
+
);
|
|
669
|
+
}
|
|
670
|
+
groupActionsByType(actions) {
|
|
671
|
+
return actions.reduce(
|
|
672
|
+
(acc, action) => {
|
|
673
|
+
if (!acc[action.action_type]) {
|
|
674
|
+
acc[action.action_type] = [];
|
|
675
|
+
}
|
|
676
|
+
acc[action.action_type].push(action);
|
|
677
|
+
return acc;
|
|
678
|
+
},
|
|
679
|
+
{}
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
createInputInterface(appName, action) {
|
|
683
|
+
const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(
|
|
684
|
+
this.sanitizeActionName(action.key)
|
|
685
|
+
)}Inputs`;
|
|
686
|
+
const properties = action.inputFields.map((field) => {
|
|
687
|
+
const fieldType = this.mapFieldTypeToTypeNode(field);
|
|
688
|
+
const isOptional = !field.required;
|
|
689
|
+
let property = this.factory.createPropertySignature(
|
|
690
|
+
void 0,
|
|
691
|
+
this.sanitizeFieldName(field.key),
|
|
692
|
+
isOptional ? this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken) : void 0,
|
|
693
|
+
fieldType
|
|
694
|
+
);
|
|
695
|
+
if (field.helpText) {
|
|
696
|
+
property = ts__namespace.addSyntheticLeadingComment(
|
|
697
|
+
property,
|
|
698
|
+
ts__namespace.SyntaxKind.MultiLineCommentTrivia,
|
|
699
|
+
`* ${this.escapeComment(field.helpText)} `,
|
|
700
|
+
true
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
return property;
|
|
704
|
+
});
|
|
705
|
+
return this.factory.createInterfaceDeclaration(
|
|
706
|
+
void 0,
|
|
707
|
+
inputTypeName,
|
|
708
|
+
void 0,
|
|
709
|
+
void 0,
|
|
710
|
+
properties
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
createActionInterface(appName, actionType, typeActions) {
|
|
714
|
+
const typeName = `${appName}${this.capitalize(actionType)}Actions`;
|
|
715
|
+
const methods = typeActions.map((action) => {
|
|
716
|
+
const actionName = this.sanitizeActionName(action.key);
|
|
717
|
+
let methodSignature;
|
|
718
|
+
if (action.inputFields.length > 0) {
|
|
719
|
+
const inputTypeName = `${appName}${this.capitalize(action.action_type)}${this.capitalize(
|
|
720
|
+
this.sanitizeActionName(action.key)
|
|
721
|
+
)}Inputs`;
|
|
722
|
+
const inputsType = this.factory.createTypeLiteralNode([
|
|
723
|
+
this.factory.createPropertySignature(
|
|
724
|
+
void 0,
|
|
725
|
+
"inputs",
|
|
726
|
+
void 0,
|
|
727
|
+
this.factory.createTypeReferenceNode(inputTypeName)
|
|
728
|
+
)
|
|
729
|
+
]);
|
|
730
|
+
const omitType = this.factory.createTypeReferenceNode("Omit", [
|
|
731
|
+
this.factory.createTypeReferenceNode("ActionExecutionOptions"),
|
|
732
|
+
this.factory.createLiteralTypeNode(
|
|
733
|
+
this.factory.createStringLiteral("inputs")
|
|
734
|
+
)
|
|
735
|
+
]);
|
|
736
|
+
const optionsType = this.factory.createIntersectionTypeNode([
|
|
737
|
+
inputsType,
|
|
738
|
+
omitType
|
|
739
|
+
]);
|
|
740
|
+
methodSignature = this.factory.createMethodSignature(
|
|
741
|
+
void 0,
|
|
742
|
+
actionName,
|
|
743
|
+
void 0,
|
|
744
|
+
void 0,
|
|
745
|
+
[
|
|
746
|
+
this.factory.createParameterDeclaration(
|
|
747
|
+
void 0,
|
|
748
|
+
void 0,
|
|
749
|
+
"options",
|
|
750
|
+
void 0,
|
|
751
|
+
optionsType
|
|
752
|
+
)
|
|
753
|
+
],
|
|
754
|
+
this.factory.createTypeReferenceNode("Promise", [
|
|
755
|
+
this.factory.createTypeReferenceNode("ActionExecutionResult")
|
|
756
|
+
])
|
|
757
|
+
);
|
|
758
|
+
} else {
|
|
759
|
+
const genericInputsType = this.factory.createTypeLiteralNode([
|
|
760
|
+
this.factory.createPropertySignature(
|
|
761
|
+
void 0,
|
|
762
|
+
"inputs",
|
|
763
|
+
this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken),
|
|
764
|
+
this.factory.createTypeReferenceNode("Record", [
|
|
765
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword),
|
|
766
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)
|
|
767
|
+
])
|
|
768
|
+
)
|
|
769
|
+
]);
|
|
770
|
+
const intersectionType = this.factory.createIntersectionTypeNode([
|
|
771
|
+
genericInputsType,
|
|
772
|
+
this.factory.createTypeReferenceNode("ActionExecutionOptions")
|
|
773
|
+
]);
|
|
774
|
+
methodSignature = this.factory.createMethodSignature(
|
|
775
|
+
void 0,
|
|
776
|
+
actionName,
|
|
777
|
+
void 0,
|
|
778
|
+
void 0,
|
|
779
|
+
[
|
|
780
|
+
this.factory.createParameterDeclaration(
|
|
781
|
+
void 0,
|
|
782
|
+
void 0,
|
|
783
|
+
"options",
|
|
784
|
+
this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken),
|
|
785
|
+
intersectionType
|
|
786
|
+
)
|
|
787
|
+
],
|
|
788
|
+
this.factory.createTypeReferenceNode("Promise", [
|
|
789
|
+
this.factory.createTypeReferenceNode("ActionExecutionResult")
|
|
790
|
+
])
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
if (action.description) {
|
|
794
|
+
methodSignature = ts__namespace.addSyntheticLeadingComment(
|
|
795
|
+
methodSignature,
|
|
796
|
+
ts__namespace.SyntaxKind.MultiLineCommentTrivia,
|
|
797
|
+
`* ${this.escapeComment(action.description)} `,
|
|
798
|
+
true
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
return methodSignature;
|
|
802
|
+
});
|
|
803
|
+
return this.factory.createInterfaceDeclaration(
|
|
804
|
+
void 0,
|
|
805
|
+
typeName,
|
|
806
|
+
void 0,
|
|
807
|
+
void 0,
|
|
808
|
+
methods
|
|
809
|
+
);
|
|
810
|
+
}
|
|
811
|
+
createAppProxyInterface(appName, actionsByType) {
|
|
812
|
+
const properties = [
|
|
813
|
+
...Object.keys(actionsByType).map(
|
|
814
|
+
(actionType) => this.factory.createPropertySignature(
|
|
815
|
+
void 0,
|
|
816
|
+
actionType,
|
|
817
|
+
void 0,
|
|
818
|
+
this.factory.createTypeReferenceNode(
|
|
819
|
+
`${appName}${this.capitalize(actionType)}Actions`
|
|
820
|
+
)
|
|
821
|
+
)
|
|
822
|
+
),
|
|
823
|
+
// Always include fetch method for authenticated HTTP requests
|
|
824
|
+
this.createFetchMethodProperty()
|
|
825
|
+
];
|
|
826
|
+
return this.factory.createInterfaceDeclaration(
|
|
827
|
+
void 0,
|
|
828
|
+
`${appName}AppProxy`,
|
|
829
|
+
void 0,
|
|
830
|
+
void 0,
|
|
831
|
+
properties
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
createFetchMethodProperty() {
|
|
835
|
+
let property = this.factory.createPropertySignature(
|
|
836
|
+
void 0,
|
|
837
|
+
"fetch",
|
|
838
|
+
void 0,
|
|
839
|
+
this.factory.createFunctionTypeNode(
|
|
840
|
+
void 0,
|
|
841
|
+
[
|
|
842
|
+
this.factory.createParameterDeclaration(
|
|
843
|
+
void 0,
|
|
844
|
+
void 0,
|
|
845
|
+
"url",
|
|
846
|
+
void 0,
|
|
847
|
+
this.factory.createUnionTypeNode([
|
|
848
|
+
this.factory.createTypeReferenceNode("string"),
|
|
849
|
+
this.factory.createTypeReferenceNode("URL")
|
|
850
|
+
])
|
|
851
|
+
),
|
|
852
|
+
this.factory.createParameterDeclaration(
|
|
853
|
+
void 0,
|
|
854
|
+
void 0,
|
|
855
|
+
"init",
|
|
856
|
+
this.factory.createToken(ts__namespace.SyntaxKind.QuestionToken),
|
|
857
|
+
this.factory.createTypeReferenceNode("ZapierFetchInitOptions")
|
|
858
|
+
)
|
|
859
|
+
],
|
|
860
|
+
this.factory.createTypeReferenceNode("Promise", [
|
|
861
|
+
this.factory.createTypeReferenceNode("Response")
|
|
862
|
+
])
|
|
863
|
+
)
|
|
864
|
+
);
|
|
865
|
+
property = ts__namespace.addSyntheticLeadingComment(
|
|
866
|
+
property,
|
|
867
|
+
ts__namespace.SyntaxKind.MultiLineCommentTrivia,
|
|
868
|
+
"* Make authenticated HTTP requests through Zapier's Relay service ",
|
|
869
|
+
true
|
|
870
|
+
);
|
|
871
|
+
return property;
|
|
872
|
+
}
|
|
873
|
+
createAppFactoryInterface(appName) {
|
|
874
|
+
const callSignature = this.factory.createCallSignature(
|
|
875
|
+
void 0,
|
|
876
|
+
[
|
|
877
|
+
this.factory.createParameterDeclaration(
|
|
878
|
+
void 0,
|
|
879
|
+
void 0,
|
|
880
|
+
"options",
|
|
881
|
+
void 0,
|
|
882
|
+
this.factory.createTypeLiteralNode([
|
|
883
|
+
this.factory.createPropertySignature(
|
|
884
|
+
void 0,
|
|
885
|
+
"authenticationId",
|
|
886
|
+
void 0,
|
|
887
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NumberKeyword)
|
|
888
|
+
)
|
|
889
|
+
])
|
|
890
|
+
)
|
|
891
|
+
],
|
|
892
|
+
this.factory.createTypeReferenceNode(`${appName}AppProxy`)
|
|
893
|
+
);
|
|
894
|
+
return this.factory.createInterfaceDeclaration(
|
|
895
|
+
void 0,
|
|
896
|
+
`${appName}AppFactory`,
|
|
897
|
+
void 0,
|
|
898
|
+
void 0,
|
|
899
|
+
[callSignature]
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
createAppWithFactoryType(appName) {
|
|
903
|
+
return this.factory.createTypeAliasDeclaration(
|
|
904
|
+
void 0,
|
|
905
|
+
`${appName}AppWithFactory`,
|
|
906
|
+
void 0,
|
|
907
|
+
this.factory.createIntersectionTypeNode([
|
|
908
|
+
this.factory.createTypeReferenceNode(`${appName}AppFactory`),
|
|
909
|
+
this.factory.createTypeReferenceNode(`${appName}AppProxy`)
|
|
910
|
+
])
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
createModuleAugmentation(appKey, appName) {
|
|
914
|
+
return this.factory.createModuleDeclaration(
|
|
915
|
+
[this.factory.createToken(ts__namespace.SyntaxKind.DeclareKeyword)],
|
|
916
|
+
this.factory.createStringLiteral("@zapier/zapier-sdk"),
|
|
917
|
+
this.factory.createModuleBlock([
|
|
918
|
+
this.factory.createInterfaceDeclaration(
|
|
919
|
+
void 0,
|
|
920
|
+
"ZapierSdkApps",
|
|
921
|
+
void 0,
|
|
922
|
+
void 0,
|
|
923
|
+
[
|
|
924
|
+
this.factory.createPropertySignature(
|
|
925
|
+
void 0,
|
|
926
|
+
appKey,
|
|
927
|
+
void 0,
|
|
928
|
+
this.factory.createTypeReferenceNode(`${appName}AppWithFactory`)
|
|
929
|
+
)
|
|
930
|
+
]
|
|
931
|
+
)
|
|
932
|
+
])
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
mapFieldTypeToTypeNode(field) {
|
|
936
|
+
if (field.choices && field.choices.length > 0) {
|
|
937
|
+
const choiceValues = field.choices.filter(
|
|
938
|
+
(choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
|
|
939
|
+
).map(
|
|
940
|
+
(choice) => typeof choice.value === "string" ? this.factory.createLiteralTypeNode(
|
|
941
|
+
this.factory.createStringLiteral(choice.value)
|
|
942
|
+
) : this.factory.createLiteralTypeNode(
|
|
943
|
+
this.factory.createNumericLiteral(String(choice.value))
|
|
944
|
+
)
|
|
945
|
+
);
|
|
946
|
+
if (choiceValues.length > 0) {
|
|
947
|
+
return this.factory.createUnionTypeNode(choiceValues);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
switch (field.type?.toLowerCase()) {
|
|
951
|
+
case "string":
|
|
952
|
+
case "text":
|
|
953
|
+
case "email":
|
|
954
|
+
case "url":
|
|
955
|
+
case "password":
|
|
956
|
+
case "datetime":
|
|
957
|
+
case "date":
|
|
958
|
+
case "file":
|
|
959
|
+
return this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword);
|
|
960
|
+
case "integer":
|
|
961
|
+
case "number":
|
|
962
|
+
return this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NumberKeyword);
|
|
963
|
+
case "boolean":
|
|
964
|
+
return this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.BooleanKeyword);
|
|
965
|
+
case "array":
|
|
966
|
+
return this.factory.createArrayTypeNode(
|
|
967
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)
|
|
968
|
+
);
|
|
969
|
+
case "object":
|
|
970
|
+
return this.factory.createTypeReferenceNode("Record", [
|
|
971
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword),
|
|
972
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)
|
|
973
|
+
]);
|
|
974
|
+
default:
|
|
975
|
+
return this.factory.createUnionTypeNode([
|
|
976
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.StringKeyword),
|
|
977
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NumberKeyword),
|
|
978
|
+
this.factory.createKeywordTypeNode(ts__namespace.SyntaxKind.BooleanKeyword)
|
|
979
|
+
]);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
generateEmptyTypesFile(appKey, version) {
|
|
983
|
+
const appName = this.capitalize(appKey);
|
|
984
|
+
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
985
|
+
return `/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */
|
|
986
|
+
/**
|
|
987
|
+
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
988
|
+
${versionComment}
|
|
989
|
+
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
990
|
+
*
|
|
991
|
+
* No actions found for this app.
|
|
992
|
+
*/
|
|
993
|
+
|
|
994
|
+
import type { ActionExecutionOptions, ActionExecutionResult, ZapierFetchInitOptions } from '@zapier/zapier-sdk'
|
|
995
|
+
|
|
996
|
+
interface ${appName}AppProxy {
|
|
997
|
+
/** Make authenticated HTTP requests through Zapier's Relay service */
|
|
998
|
+
fetch: (url: string | URL, init?: ZapierFetchInitOptions) => Promise<Response>
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
interface ${appName}AppFactory {
|
|
1002
|
+
(options: { authenticationId: number }): ${appName}AppProxy
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
1006
|
+
|
|
1007
|
+
declare module "@zapier/zapier-sdk" {
|
|
1008
|
+
interface ZapierSdkApps {
|
|
1009
|
+
${appKey}: ${appName}AppWithFactory
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
`;
|
|
1013
|
+
}
|
|
1014
|
+
capitalize(str) {
|
|
1015
|
+
return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
|
|
1016
|
+
}
|
|
1017
|
+
sanitizeActionName(actionKey) {
|
|
1018
|
+
let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1019
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
1020
|
+
sanitized = "_" + sanitized;
|
|
1021
|
+
}
|
|
1022
|
+
return sanitized;
|
|
1023
|
+
}
|
|
1024
|
+
sanitizeFieldName(fieldKey) {
|
|
1025
|
+
let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1026
|
+
if (/^[0-9]/.test(sanitized)) {
|
|
1027
|
+
sanitized = "_" + sanitized;
|
|
1028
|
+
}
|
|
1029
|
+
return sanitized;
|
|
1030
|
+
}
|
|
1031
|
+
escapeComment(comment) {
|
|
1032
|
+
return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
async function detectTypesOutputDirectory() {
|
|
1036
|
+
const candidates = ["src", "lib"];
|
|
1037
|
+
for (const candidate of candidates) {
|
|
1038
|
+
try {
|
|
1039
|
+
await promises.access(candidate);
|
|
1040
|
+
return path.join(candidate, "zapier", "apps");
|
|
1041
|
+
} catch {
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
return "./zapier/apps/";
|
|
1045
|
+
}
|
|
1046
|
+
var addPlugin = ({ sdk, context }) => {
|
|
1047
|
+
const add = zapierSdk.createFunction(async function add2(options) {
|
|
1048
|
+
const {
|
|
1049
|
+
appKeys,
|
|
1050
|
+
authenticationIds,
|
|
1051
|
+
configPath,
|
|
1052
|
+
typesOutput = await detectTypesOutputDirectory()
|
|
1053
|
+
} = options;
|
|
1054
|
+
const resolvedTypesOutput = path.resolve(typesOutput);
|
|
1055
|
+
await promises.mkdir(resolvedTypesOutput, { recursive: true });
|
|
1056
|
+
console.log(`\u{1F4E6} Looking up ${appKeys.length} app(s)...`);
|
|
1057
|
+
const appsIterator = sdk.listApps({ appKeys }).items();
|
|
1058
|
+
const apps = [];
|
|
1059
|
+
for await (const app of appsIterator) {
|
|
1060
|
+
apps.push(app);
|
|
1061
|
+
}
|
|
1062
|
+
if (apps.length === 0) {
|
|
1063
|
+
console.warn("\u26A0\uFE0F No apps found");
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
let authentications = [];
|
|
1067
|
+
if (authenticationIds && authenticationIds.length > 0) {
|
|
1068
|
+
console.log(
|
|
1069
|
+
`\u{1F510} Looking up ${authenticationIds.length} authentication(s)...`
|
|
1070
|
+
);
|
|
1071
|
+
const authsIterator = sdk.listAuthentications({ authenticationIds }).items();
|
|
1072
|
+
for await (const auth of authsIterator) {
|
|
1073
|
+
authentications.push(auth);
|
|
1074
|
+
}
|
|
1075
|
+
console.log(`\u{1F510} Found ${authentications.length} authentication(s)`);
|
|
1076
|
+
}
|
|
1077
|
+
for (const app of apps) {
|
|
1078
|
+
const appSlugAndKey = app.slug ? `${app.slug} (${app.key})` : app.key;
|
|
1079
|
+
console.log(`\u{1F4E6} Adding ${appSlugAndKey}...`);
|
|
1080
|
+
try {
|
|
1081
|
+
if (!app.version) {
|
|
1082
|
+
console.warn(
|
|
1083
|
+
`\u26A0\uFE0F Invalid implementation ID format for '${appSlugAndKey}': ${app.implementation_id}. Expected format: <implementationName>@<version>. Skipping...`
|
|
1084
|
+
);
|
|
1085
|
+
continue;
|
|
1086
|
+
}
|
|
1087
|
+
const [manifestKey] = await context.updateManifestEntry(
|
|
1088
|
+
app.key,
|
|
1089
|
+
{
|
|
1090
|
+
implementationName: app.key,
|
|
1091
|
+
version: app.version
|
|
1092
|
+
},
|
|
1093
|
+
configPath
|
|
1094
|
+
);
|
|
1095
|
+
console.log(
|
|
1096
|
+
`\u{1F4DD} Locked ${appSlugAndKey} to ${app.key}@${app.version} using key '${manifestKey}'`
|
|
1097
|
+
);
|
|
1098
|
+
let authenticationId;
|
|
1099
|
+
if (authentications.length > 0) {
|
|
1100
|
+
const matchingAuth = authentications.find((auth) => {
|
|
1101
|
+
return auth.app_key === app.key;
|
|
1102
|
+
});
|
|
1103
|
+
if (matchingAuth) {
|
|
1104
|
+
authenticationId = matchingAuth.id;
|
|
1105
|
+
console.log(
|
|
1106
|
+
`\u{1F510} Using authentication ${authenticationId} (${matchingAuth.title}) for ${appSlugAndKey}`
|
|
1107
|
+
);
|
|
1108
|
+
} else {
|
|
1109
|
+
console.warn(
|
|
1110
|
+
`\u26A0\uFE0F No matching authentication found for ${appSlugAndKey}`
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
const typesPath = path.join(resolvedTypesOutput, `${manifestKey}.d.ts`);
|
|
1115
|
+
try {
|
|
1116
|
+
const generator = new AstTypeGenerator();
|
|
1117
|
+
const typeDefinitions = await generator.generateTypes({
|
|
1118
|
+
appKey: manifestKey,
|
|
1119
|
+
authenticationId,
|
|
1120
|
+
sdk
|
|
1121
|
+
});
|
|
1122
|
+
await promises.writeFile(typesPath, typeDefinitions, "utf8");
|
|
1123
|
+
console.log(`\u{1F527} Generated types for ${manifestKey} at ${typesPath}`);
|
|
1124
|
+
} catch (error) {
|
|
1125
|
+
console.warn(
|
|
1126
|
+
`\u26A0\uFE0F Failed to generate types for ${appSlugAndKey}: ${error}`
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
} catch (error) {
|
|
1130
|
+
console.warn(`\u26A0\uFE0F Failed to process ${appSlugAndKey}: ${error}`);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
console.log(`\u2705 Added ${apps.length} app(s) to manifest`);
|
|
1134
|
+
}, AddSchema);
|
|
1135
|
+
return {
|
|
1136
|
+
add,
|
|
744
1137
|
context: {
|
|
745
1138
|
meta: {
|
|
746
|
-
|
|
1139
|
+
add: {
|
|
747
1140
|
categories: ["utility"],
|
|
748
|
-
inputSchema:
|
|
1141
|
+
inputSchema: AddSchema
|
|
749
1142
|
}
|
|
750
1143
|
}
|
|
751
1144
|
}
|
|
@@ -757,9 +1150,9 @@ function createZapierCliSdk(options = {}) {
|
|
|
757
1150
|
let sdk = zapierSdk.createZapierSdkWithoutRegistry({
|
|
758
1151
|
debug: options.debug
|
|
759
1152
|
});
|
|
760
|
-
sdk = sdk.addPlugin(generateTypesPlugin);
|
|
761
1153
|
sdk = sdk.addPlugin(bundleCodePlugin);
|
|
762
|
-
sdk = sdk.addPlugin(
|
|
1154
|
+
sdk = sdk.addPlugin(getLoginConfigPathPlugin);
|
|
1155
|
+
sdk = sdk.addPlugin(addPlugin);
|
|
763
1156
|
sdk = sdk.addPlugin(mcpPlugin);
|
|
764
1157
|
sdk = sdk.addPlugin(loginPlugin);
|
|
765
1158
|
sdk = sdk.addPlugin(logoutPlugin);
|