@zapier/zapier-sdk 0.4.0 → 0.5.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 +7 -0
- package/dist/api/auth.d.ts +9 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +25 -0
- package/dist/api/client.d.ts +9 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +322 -0
- package/dist/api/debug.d.ts +13 -0
- package/dist/api/debug.d.ts.map +1 -0
- package/dist/api/debug.js +55 -0
- package/dist/api/index.d.ts +29 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +41 -0
- package/dist/api/polling.d.ts +16 -0
- package/dist/api/polling.d.ts.map +1 -0
- package/dist/api/polling.js +45 -0
- package/dist/api/schemas.d.ts +2473 -0
- package/dist/api/schemas.d.ts.map +1 -0
- package/dist/api/schemas.js +355 -0
- package/dist/api/types.d.ts +75 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +11 -0
- package/dist/auth.d.ts +34 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +47 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/index.cjs +2134 -1444
- package/dist/index.d.mts +2456 -584
- package/dist/index.d.ts +17 -840
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.mjs +2118 -1428
- package/dist/plugins/api/index.d.ts +14 -0
- package/dist/plugins/api/index.d.ts.map +1 -0
- package/dist/plugins/api/index.js +21 -0
- package/dist/plugins/apps/index.d.ts +11 -0
- package/dist/plugins/apps/index.d.ts.map +1 -0
- package/dist/plugins/apps/index.js +91 -0
- package/dist/plugins/apps/types.d.ts +30 -0
- package/dist/plugins/apps/types.d.ts.map +1 -0
- package/dist/plugins/apps/types.js +2 -0
- package/dist/plugins/fetch/index.d.ts +21 -0
- package/dist/plugins/fetch/index.d.ts.map +1 -0
- package/dist/plugins/fetch/index.js +20 -0
- package/dist/plugins/findFirstAuthentication/index.d.ts +20 -0
- package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -0
- package/dist/plugins/findFirstAuthentication/index.js +24 -0
- package/dist/plugins/findFirstAuthentication/index.test.d.ts +2 -0
- package/dist/plugins/findFirstAuthentication/index.test.d.ts.map +1 -0
- package/dist/plugins/findFirstAuthentication/index.test.js +171 -0
- package/dist/plugins/findFirstAuthentication/schemas.d.ts +29 -0
- package/dist/plugins/findFirstAuthentication/schemas.d.ts.map +1 -0
- package/dist/plugins/findFirstAuthentication/schemas.js +18 -0
- package/dist/plugins/findUniqueAuthentication/index.d.ts +20 -0
- package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -0
- package/dist/plugins/findUniqueAuthentication/index.js +31 -0
- package/dist/plugins/findUniqueAuthentication/index.test.d.ts +2 -0
- package/dist/plugins/findUniqueAuthentication/index.test.d.ts.map +1 -0
- package/dist/plugins/findUniqueAuthentication/index.test.js +152 -0
- package/dist/plugins/findUniqueAuthentication/schemas.d.ts +29 -0
- package/dist/plugins/findUniqueAuthentication/schemas.d.ts.map +1 -0
- package/dist/plugins/findUniqueAuthentication/schemas.js +18 -0
- package/dist/plugins/getAction/index.d.ts +23 -0
- package/dist/plugins/getAction/index.d.ts.map +1 -0
- package/dist/plugins/getAction/index.js +28 -0
- package/dist/plugins/getAction/index.test.d.ts +2 -0
- package/dist/plugins/getAction/index.test.d.ts.map +1 -0
- package/dist/plugins/getAction/index.test.js +186 -0
- package/dist/plugins/getAction/schemas.d.ts +23 -0
- package/dist/plugins/getAction/schemas.d.ts.map +1 -0
- package/dist/plugins/getAction/schemas.js +10 -0
- package/dist/plugins/getApp/index.d.ts +22 -0
- package/dist/plugins/getApp/index.d.ts.map +1 -0
- package/dist/plugins/getApp/index.js +39 -0
- package/dist/plugins/getApp/index.test.d.ts +2 -0
- package/dist/plugins/getApp/index.test.d.ts.map +1 -0
- package/dist/plugins/getApp/index.test.js +100 -0
- package/dist/plugins/getApp/schemas.d.ts +18 -0
- package/dist/plugins/getApp/schemas.d.ts.map +1 -0
- package/dist/plugins/getApp/schemas.js +10 -0
- package/dist/plugins/getAuthentication/index.d.ts +22 -0
- package/dist/plugins/getAuthentication/index.d.ts.map +1 -0
- package/dist/plugins/getAuthentication/index.js +41 -0
- package/dist/plugins/getAuthentication/index.test.d.ts +2 -0
- package/dist/plugins/getAuthentication/index.test.d.ts.map +1 -0
- package/dist/plugins/getAuthentication/index.test.js +205 -0
- package/dist/plugins/getAuthentication/schemas.d.ts +17 -0
- package/dist/plugins/getAuthentication/schemas.d.ts.map +1 -0
- package/dist/plugins/getAuthentication/schemas.js +11 -0
- package/dist/plugins/getProfile/index.d.ts +23 -0
- package/dist/plugins/getProfile/index.d.ts.map +1 -0
- package/dist/plugins/getProfile/index.js +29 -0
- package/dist/plugins/getProfile/schemas.d.ts +13 -0
- package/dist/plugins/getProfile/schemas.d.ts.map +1 -0
- package/dist/plugins/getProfile/schemas.js +5 -0
- package/dist/plugins/listActions/index.d.ts +28 -0
- package/dist/plugins/listActions/index.d.ts.map +1 -0
- package/dist/plugins/listActions/index.js +61 -0
- package/dist/plugins/listActions/index.test.d.ts +2 -0
- package/dist/plugins/listActions/index.test.d.ts.map +1 -0
- package/dist/plugins/listActions/index.test.js +467 -0
- package/dist/plugins/listActions/schemas.d.ts +29 -0
- package/dist/plugins/listActions/schemas.d.ts.map +1 -0
- package/dist/plugins/listActions/schemas.js +21 -0
- package/dist/plugins/listApps/index.d.ts +28 -0
- package/dist/plugins/listApps/index.d.ts.map +1 -0
- package/dist/plugins/listApps/index.js +62 -0
- package/dist/plugins/listApps/index.test.d.ts +2 -0
- package/dist/plugins/listApps/index.test.d.ts.map +1 -0
- package/dist/plugins/listApps/index.test.js +313 -0
- package/dist/plugins/listApps/schemas.d.ts +30 -0
- package/dist/plugins/listApps/schemas.d.ts.map +1 -0
- package/dist/plugins/listApps/schemas.js +23 -0
- package/dist/plugins/listAuthentications/index.d.ts +28 -0
- package/dist/plugins/listAuthentications/index.d.ts.map +1 -0
- package/dist/plugins/listAuthentications/index.js +77 -0
- package/dist/plugins/listAuthentications/index.test.d.ts +2 -0
- package/dist/plugins/listAuthentications/index.test.d.ts.map +1 -0
- package/dist/plugins/listAuthentications/index.test.js +564 -0
- package/dist/plugins/listAuthentications/schemas.d.ts +38 -0
- package/dist/plugins/listAuthentications/schemas.d.ts.map +1 -0
- package/dist/plugins/listAuthentications/schemas.js +28 -0
- package/dist/plugins/listInputFields/index.d.ts +28 -0
- package/dist/plugins/listInputFields/index.d.ts.map +1 -0
- package/dist/plugins/listInputFields/index.js +133 -0
- package/dist/plugins/listInputFields/index.test.d.ts +2 -0
- package/dist/plugins/listInputFields/index.test.d.ts.map +1 -0
- package/dist/plugins/listInputFields/index.test.js +325 -0
- package/dist/plugins/listInputFields/schemas.d.ts +38 -0
- package/dist/plugins/listInputFields/schemas.d.ts.map +1 -0
- package/dist/plugins/listInputFields/schemas.js +22 -0
- package/dist/plugins/registry/index.d.ts +11 -0
- package/dist/plugins/registry/index.d.ts.map +1 -0
- package/dist/plugins/registry/index.js +14 -0
- package/dist/plugins/request/index.d.ts +19 -0
- package/dist/plugins/request/index.d.ts.map +1 -0
- package/dist/plugins/request/index.js +62 -0
- package/dist/plugins/request/index.test.d.ts +2 -0
- package/dist/plugins/request/index.test.d.ts.map +1 -0
- package/dist/plugins/request/index.test.js +256 -0
- package/dist/plugins/request/schemas.d.ts +69 -0
- package/dist/plugins/request/schemas.d.ts.map +1 -0
- package/dist/plugins/request/schemas.js +42 -0
- package/dist/plugins/runAction/index.d.ts +28 -0
- package/dist/plugins/runAction/index.d.ts.map +1 -0
- package/dist/plugins/runAction/index.js +86 -0
- package/dist/plugins/runAction/index.test.d.ts +2 -0
- package/dist/plugins/runAction/index.test.d.ts.map +1 -0
- package/dist/plugins/runAction/index.test.js +320 -0
- package/dist/plugins/runAction/schemas.d.ts +37 -0
- package/dist/plugins/runAction/schemas.d.ts.map +1 -0
- package/dist/plugins/runAction/schemas.js +22 -0
- package/dist/resolvers/actionKey.d.ts +9 -0
- package/dist/resolvers/actionKey.d.ts.map +1 -0
- package/dist/resolvers/actionKey.js +19 -0
- package/dist/resolvers/actionType.d.ts +9 -0
- package/dist/resolvers/actionType.d.ts.map +1 -0
- package/dist/resolvers/actionType.js +22 -0
- package/dist/resolvers/appKey.d.ts +7 -0
- package/dist/resolvers/appKey.d.ts.map +1 -0
- package/dist/resolvers/appKey.js +5 -0
- package/dist/resolvers/authenticationId.d.ts +9 -0
- package/dist/resolvers/authenticationId.d.ts.map +1 -0
- package/dist/resolvers/authenticationId.js +33 -0
- package/dist/resolvers/index.d.ts +40 -0
- package/dist/resolvers/index.d.ts.map +1 -0
- package/dist/resolvers/index.js +91 -0
- package/dist/resolvers/inputs.d.ts +8 -0
- package/dist/resolvers/inputs.d.ts.map +1 -0
- package/dist/resolvers/inputs.js +14 -0
- package/dist/schemas/Action.d.ts +243 -0
- package/dist/schemas/Action.d.ts.map +1 -0
- package/dist/schemas/Action.js +34 -0
- package/dist/schemas/App.d.ts +26 -0
- package/dist/schemas/App.d.ts.map +1 -0
- package/dist/schemas/App.js +22 -0
- package/dist/schemas/Auth.d.ts +161 -0
- package/dist/schemas/Auth.d.ts.map +1 -0
- package/dist/schemas/Auth.js +41 -0
- package/dist/schemas/Field.d.ts +144 -0
- package/dist/schemas/Field.d.ts.map +1 -0
- package/dist/schemas/Field.js +105 -0
- package/dist/schemas/UserProfile.d.ts +163 -0
- package/dist/schemas/UserProfile.d.ts.map +1 -0
- package/dist/schemas/UserProfile.js +29 -0
- package/dist/sdk.d.ts +10 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +94 -0
- package/dist/sdk.test.d.ts +2 -0
- package/dist/sdk.test.d.ts.map +1 -0
- package/dist/sdk.test.js +135 -0
- package/dist/types/domain.d.ts +36 -0
- package/dist/types/domain.d.ts.map +1 -0
- package/dist/types/domain.js +1 -0
- package/dist/types/domain.test.d.ts +2 -0
- package/dist/types/domain.test.d.ts.map +1 -0
- package/dist/types/domain.test.js +39 -0
- package/dist/types/errors.d.ts +143 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +187 -0
- package/dist/types/events.d.ts +38 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +7 -0
- package/dist/types/functions.d.ts +26 -0
- package/dist/types/functions.d.ts.map +1 -0
- package/dist/types/functions.js +4 -0
- package/dist/types/plugin.d.ts +61 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +9 -0
- package/dist/types/properties.d.ts +22 -0
- package/dist/types/properties.d.ts.map +1 -0
- package/dist/types/properties.js +50 -0
- package/dist/types/sdk.d.ts +43 -0
- package/dist/types/sdk.d.ts.map +1 -0
- package/dist/types/sdk.js +4 -0
- package/dist/utils/array-utils.d.ts +31 -0
- package/dist/utils/array-utils.d.ts.map +1 -0
- package/dist/utils/array-utils.js +36 -0
- package/dist/utils/array-utils.test.d.ts +2 -0
- package/dist/utils/array-utils.test.d.ts.map +1 -0
- package/dist/utils/array-utils.test.js +107 -0
- package/dist/utils/domain-utils.d.ts +78 -0
- package/dist/utils/domain-utils.d.ts.map +1 -0
- package/dist/utils/domain-utils.js +218 -0
- package/dist/utils/domain-utils.test.d.ts +2 -0
- package/dist/utils/domain-utils.test.d.ts.map +1 -0
- package/dist/utils/domain-utils.test.js +192 -0
- package/dist/utils/function-utils.d.ts +45 -0
- package/dist/utils/function-utils.d.ts.map +1 -0
- package/dist/utils/function-utils.js +158 -0
- package/dist/utils/function-utils.test.d.ts +2 -0
- package/dist/utils/function-utils.test.d.ts.map +1 -0
- package/dist/utils/function-utils.test.js +110 -0
- package/dist/utils/pagination-utils.d.ts +37 -0
- package/dist/utils/pagination-utils.d.ts.map +1 -0
- package/dist/utils/pagination-utils.js +165 -0
- package/dist/utils/pagination-utils.test.d.ts +17 -0
- package/dist/utils/pagination-utils.test.d.ts.map +1 -0
- package/dist/utils/pagination-utils.test.js +461 -0
- package/dist/utils/schema-utils.d.ts +45 -0
- package/dist/utils/schema-utils.d.ts.map +1 -0
- package/dist/utils/schema-utils.js +65 -0
- package/dist/utils/validation.d.ts +4 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +30 -0
- package/dist/utils/validation.test.d.ts +2 -0
- package/dist/utils/validation.test.d.ts.map +1 -0
- package/dist/utils/validation.test.js +43 -0
- package/package.json +12 -3
- package/src/api/client.ts +403 -167
- package/src/api/debug.ts +10 -1
- package/src/api/index.ts +0 -2
- package/src/api/polling.ts +31 -14
- package/src/api/schemas.ts +387 -0
- package/src/api/types.ts +73 -138
- package/src/constants.ts +10 -0
- package/src/index.ts +45 -20
- package/src/plugins/api/index.ts +47 -0
- package/src/plugins/apps/index.ts +36 -31
- package/src/plugins/apps/types.ts +24 -12
- package/src/plugins/fetch/index.ts +58 -0
- package/src/plugins/findFirstAuthentication/index.test.ts +206 -0
- package/src/plugins/findFirstAuthentication/index.ts +55 -0
- package/src/plugins/findFirstAuthentication/schemas.ts +41 -0
- package/src/plugins/findUniqueAuthentication/index.test.ts +197 -0
- package/src/plugins/findUniqueAuthentication/index.ts +72 -0
- package/src/plugins/findUniqueAuthentication/schemas.ts +42 -0
- package/src/plugins/getAction/index.test.ts +239 -0
- package/src/plugins/getAction/index.ts +57 -0
- package/src/plugins/getAction/schemas.ts +33 -0
- package/src/plugins/getApp/index.test.ts +127 -0
- package/src/plugins/getApp/index.ts +66 -0
- package/src/plugins/getApp/schemas.ts +38 -0
- package/src/plugins/getAuthentication/index.test.ts +284 -0
- package/src/plugins/getAuthentication/index.ts +86 -0
- package/src/plugins/getAuthentication/schemas.ts +31 -0
- package/src/plugins/getProfile/index.ts +55 -0
- package/src/plugins/getProfile/schemas.ts +26 -0
- package/src/plugins/listActions/index.test.ts +582 -0
- package/src/plugins/listActions/index.ts +115 -0
- package/src/plugins/listActions/schemas.ts +54 -0
- package/src/plugins/listApps/index.test.ts +357 -0
- package/src/plugins/listApps/index.ts +121 -0
- package/src/plugins/listApps/schemas.ts +49 -0
- package/src/plugins/listAuthentications/index.test.ts +709 -0
- package/src/plugins/listAuthentications/index.ts +136 -0
- package/src/plugins/listAuthentications/schemas.ts +60 -0
- package/src/plugins/listInputFields/index.test.ts +408 -0
- package/src/plugins/listInputFields/index.ts +204 -0
- package/src/plugins/listInputFields/schemas.ts +56 -0
- package/src/plugins/registry/index.ts +30 -0
- package/src/plugins/request/index.test.ts +329 -0
- package/src/plugins/request/index.ts +103 -0
- package/src/plugins/request/schemas.ts +64 -0
- package/src/plugins/runAction/index.test.ts +387 -0
- package/src/plugins/runAction/index.ts +176 -0
- package/src/plugins/runAction/schemas.ts +53 -0
- package/src/resolvers/actionKey.ts +6 -4
- package/src/resolvers/actionType.ts +7 -2
- package/src/resolvers/appKey.ts +1 -1
- package/src/resolvers/authenticationId.ts +12 -3
- package/src/resolvers/inputs.ts +3 -1
- package/src/schemas/Action.ts +18 -12
- package/src/schemas/App.ts +11 -19
- package/src/schemas/Auth.ts +18 -13
- package/src/schemas/Field.ts +106 -11
- package/src/schemas/UserProfile.ts +43 -0
- package/src/sdk.test.ts +212 -0
- package/src/sdk.ts +133 -105
- package/src/types/domain.test.ts +50 -0
- package/src/types/domain.ts +43 -75
- package/src/types/errors.ts +275 -0
- package/src/types/functions.ts +27 -0
- package/src/types/optional-zapier-sdk-cli-login.d.ts +37 -0
- package/src/types/plugin.ts +105 -0
- package/src/types/properties.ts +4 -3
- package/src/types/sdk.ts +71 -46
- package/src/utils/array-utils.test.ts +131 -0
- package/src/utils/array-utils.ts +41 -0
- package/src/utils/domain-utils.test.ts +239 -0
- package/src/utils/domain-utils.ts +283 -0
- package/src/utils/function-utils.test.ts +141 -0
- package/src/utils/function-utils.ts +245 -0
- package/src/utils/pagination-utils.test.ts +620 -0
- package/src/utils/pagination-utils.ts +242 -0
- package/src/utils/validation.test.ts +50 -0
- package/src/utils/validation.ts +44 -0
- package/tsconfig.build.json +16 -2
- package/tsconfig.json +3 -1
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +2 -0
- package/src/functions/bundleCode/index.ts +0 -78
- package/src/functions/bundleCode/info.ts +0 -9
- package/src/functions/bundleCode/schemas.ts +0 -30
- package/src/functions/fetch/index.ts +0 -180
- package/src/functions/fetch/info.ts +0 -8
- package/src/functions/fetch/schemas.ts +0 -46
- package/src/functions/findFirstAuthentication/index.ts +0 -24
- package/src/functions/findFirstAuthentication/info.ts +0 -9
- package/src/functions/findFirstAuthentication/schemas.ts +0 -50
- package/src/functions/findUniqueAuthentication/index.ts +0 -35
- package/src/functions/findUniqueAuthentication/info.ts +0 -9
- package/src/functions/findUniqueAuthentication/schemas.ts +0 -50
- package/src/functions/generateTypes/index.ts +0 -363
- package/src/functions/generateTypes/info.ts +0 -9
- package/src/functions/generateTypes/schemas.ts +0 -31
- package/src/functions/getAction/index.ts +0 -33
- package/src/functions/getAction/info.ts +0 -9
- package/src/functions/getAction/schemas.ts +0 -25
- package/src/functions/getApp/index.ts +0 -41
- package/src/functions/getApp/info.ts +0 -9
- package/src/functions/getApp/schemas.ts +0 -20
- package/src/functions/getAuthentication/index.ts +0 -50
- package/src/functions/getAuthentication/info.ts +0 -9
- package/src/functions/getAuthentication/schemas.ts +0 -29
- package/src/functions/listActions/index.ts +0 -149
- package/src/functions/listActions/info.ts +0 -9
- package/src/functions/listActions/schemas.ts +0 -30
- package/src/functions/listApps/index.ts +0 -60
- package/src/functions/listApps/info.ts +0 -9
- package/src/functions/listApps/schemas.ts +0 -32
- package/src/functions/listAuthentications/index.ts +0 -162
- package/src/functions/listAuthentications/info.ts +0 -9
- package/src/functions/listAuthentications/schemas.ts +0 -50
- package/src/functions/listFields/index.ts +0 -86
- package/src/functions/listFields/info.ts +0 -9
- package/src/functions/listFields/schemas.ts +0 -36
- package/src/functions/runAction/index.ts +0 -127
- package/src/functions/runAction/info.ts +0 -9
- package/src/functions/runAction/schemas.ts +0 -34
- package/src/plugins/apps/info.ts +0 -12
- /package/src/{schema-utils.ts → utils/schema-utils.ts} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,86 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __esm = (fn, res) => function __init() {
|
|
6
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
-
};
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// src/auth.ts
|
|
14
|
-
var auth_exports = {};
|
|
15
|
-
__export(auth_exports, {
|
|
16
|
-
getTokenFromCliLogin: () => getTokenFromCliLogin,
|
|
17
|
-
getTokenFromEnv: () => getTokenFromEnv,
|
|
18
|
-
getTokenFromEnvOrConfig: () => getTokenFromEnvOrConfig
|
|
19
|
-
});
|
|
20
|
-
function getTokenFromEnv() {
|
|
21
|
-
return process.env.ZAPIER_TOKEN;
|
|
22
|
-
}
|
|
23
|
-
async function getTokenFromCliLogin(options = {}) {
|
|
24
|
-
try {
|
|
25
|
-
const { getToken } = await import('@zapier/zapier-sdk-cli-login');
|
|
26
|
-
return await getToken(options);
|
|
27
|
-
} catch {
|
|
28
|
-
return void 0;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async function getTokenFromEnvOrConfig(options = {}) {
|
|
32
|
-
const envToken = getTokenFromEnv();
|
|
33
|
-
if (envToken) {
|
|
34
|
-
return envToken;
|
|
35
|
-
}
|
|
36
|
-
return getTokenFromCliLogin(options);
|
|
37
|
-
}
|
|
38
|
-
var init_auth = __esm({
|
|
39
|
-
"src/auth.ts"() {
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// src/api/auth.ts
|
|
44
|
-
var auth_exports2 = {};
|
|
45
|
-
__export(auth_exports2, {
|
|
46
|
-
getAuthorizationHeader: () => getAuthorizationHeader,
|
|
47
|
-
isJwt: () => isJwt
|
|
48
|
-
});
|
|
49
|
-
function isJwt(token) {
|
|
50
|
-
const parts = token.split(".");
|
|
51
|
-
if (parts.length !== 3) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
const base64UrlPattern = /^[A-Za-z0-9_-]+$/;
|
|
55
|
-
return parts.every((part) => part.length > 0 && base64UrlPattern.test(part));
|
|
56
|
-
}
|
|
57
|
-
function getAuthorizationHeader(token) {
|
|
58
|
-
if (isJwt(token)) {
|
|
59
|
-
return `JWT ${token}`;
|
|
60
|
-
}
|
|
61
|
-
return `Bearer ${token}`;
|
|
62
|
-
}
|
|
63
|
-
var init_auth2 = __esm({
|
|
64
|
-
"src/api/auth.ts"() {
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// src/types/domain.ts
|
|
69
|
-
var ZapierSdkError = class extends Error {
|
|
70
|
-
constructor(message, code) {
|
|
71
|
-
super(message);
|
|
72
|
-
this.code = code;
|
|
73
|
-
this.name = "ZapierSdkError";
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
var AppNotFoundError = class extends ZapierSdkError {
|
|
77
|
-
constructor(appKey) {
|
|
78
|
-
super(`App "${appKey}" not found`);
|
|
79
|
-
this.name = "AppNotFoundError";
|
|
80
|
-
this.code = "APP_NOT_FOUND";
|
|
81
|
-
this.appKey = appKey;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
3
|
+
// src/types/properties.ts
|
|
84
4
|
function withFormatter(schema, formatMeta) {
|
|
85
5
|
schema._def.formatMeta = formatMeta;
|
|
86
6
|
return schema;
|
|
@@ -106,9 +26,12 @@ function isPositional(schema) {
|
|
|
106
26
|
return false;
|
|
107
27
|
}
|
|
108
28
|
|
|
29
|
+
// src/constants.ts
|
|
30
|
+
var MAX_PAGE_LIMIT = 1e4;
|
|
31
|
+
|
|
109
32
|
// src/types/properties.ts
|
|
110
33
|
var AppKeyPropertySchema = withPositional(
|
|
111
|
-
z.string().min(1).describe("App
|
|
34
|
+
z.string().min(1).describe("App key (e.g., 'SlackCLIAPI')")
|
|
112
35
|
);
|
|
113
36
|
var ActionTypePropertySchema = z.enum([
|
|
114
37
|
"read",
|
|
@@ -123,20 +46,155 @@ var ActionTypePropertySchema = z.enum([
|
|
|
123
46
|
var ActionKeyPropertySchema = z.string().min(1).describe("Action key to execute");
|
|
124
47
|
var AuthenticationIdPropertySchema = z.number().int().describe("Authentication ID to use for this action");
|
|
125
48
|
var InputsPropertySchema = z.record(z.any()).describe("Input parameters for the action");
|
|
126
|
-
var LimitPropertySchema = z.number().int().min(1).max(
|
|
49
|
+
var LimitPropertySchema = z.number().int().min(1).max(MAX_PAGE_LIMIT).default(50).describe("Maximum number of items to return");
|
|
127
50
|
var OffsetPropertySchema = z.number().int().min(0).default(0).describe("Number of items to skip for pagination");
|
|
128
51
|
var OutputPropertySchema = z.string().describe("Output file path");
|
|
129
52
|
var DebugPropertySchema = z.boolean().default(false).describe("Enable debug logging");
|
|
130
53
|
var ParamsPropertySchema = z.record(z.any()).describe("Additional parameters");
|
|
131
54
|
|
|
55
|
+
// src/types/errors.ts
|
|
56
|
+
var ZapierError = class extends Error {
|
|
57
|
+
constructor(message, options = {}) {
|
|
58
|
+
super(message);
|
|
59
|
+
this.statusCode = options.statusCode;
|
|
60
|
+
this.errors = options.errors;
|
|
61
|
+
this.cause = options.cause;
|
|
62
|
+
this.response = options.response;
|
|
63
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var ZapierApiError = class extends ZapierError {
|
|
67
|
+
constructor(message, options = {}) {
|
|
68
|
+
super(message, options);
|
|
69
|
+
this.name = "ZapierApiError";
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var ZapierAppNotFoundError = class extends ZapierError {
|
|
73
|
+
constructor(message, options = {}) {
|
|
74
|
+
super(message, options);
|
|
75
|
+
this.name = "ZapierAppNotFoundError";
|
|
76
|
+
this.appKey = options.appKey;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var ZapierValidationError = class extends ZapierError {
|
|
80
|
+
constructor(message, options = {}) {
|
|
81
|
+
super(message, options);
|
|
82
|
+
this.name = "ZapierValidationError";
|
|
83
|
+
this.details = options.details;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var ZapierUnknownError = class extends ZapierError {
|
|
87
|
+
constructor(message, options = {}) {
|
|
88
|
+
super(message, options);
|
|
89
|
+
this.name = "ZapierUnknownError";
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var ZapierAuthenticationError = class extends ZapierError {
|
|
93
|
+
constructor(message, options = {}) {
|
|
94
|
+
super(message, options);
|
|
95
|
+
this.name = "ZapierAuthenticationError";
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var ZapierResourceNotFoundError = class extends ZapierError {
|
|
99
|
+
constructor(message, options = {}) {
|
|
100
|
+
super(message, options);
|
|
101
|
+
this.name = "ZapierResourceNotFoundError";
|
|
102
|
+
this.resourceType = options.resourceType;
|
|
103
|
+
this.resourceId = options.resourceId;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
var ZapierConfigurationError = class extends ZapierError {
|
|
107
|
+
constructor(message, options = {}) {
|
|
108
|
+
super(message, options);
|
|
109
|
+
this.name = "ZapierConfigurationError";
|
|
110
|
+
this.configType = options.configType;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
var ZapierBundleError = class extends ZapierError {
|
|
114
|
+
constructor(message, options = {}) {
|
|
115
|
+
super(message, options);
|
|
116
|
+
this.name = "ZapierBundleError";
|
|
117
|
+
this.buildErrors = options.buildErrors;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
var ZapierTimeoutError = class extends ZapierError {
|
|
121
|
+
constructor(message, options = {}) {
|
|
122
|
+
super(message, options);
|
|
123
|
+
this.name = "ZapierTimeoutError";
|
|
124
|
+
this.attempts = options.attempts;
|
|
125
|
+
this.maxAttempts = options.maxAttempts;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
var ZapierActionError = class extends ZapierError {
|
|
129
|
+
constructor(message, options = {}) {
|
|
130
|
+
super(message, options);
|
|
131
|
+
this.name = "ZapierActionError";
|
|
132
|
+
this.appKey = options.appKey;
|
|
133
|
+
this.actionKey = options.actionKey;
|
|
134
|
+
}
|
|
135
|
+
// Legacy accessor for backward compatibility
|
|
136
|
+
get actionErrors() {
|
|
137
|
+
return this.errors;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var ZapierNotFoundError = class extends ZapierError {
|
|
141
|
+
constructor(message, options = {}) {
|
|
142
|
+
super(message, options);
|
|
143
|
+
this.name = "ZapierNotFoundError";
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
function formatErrorMessage(error) {
|
|
147
|
+
let message = error.message;
|
|
148
|
+
if (error.errors && error.errors.length > 0) {
|
|
149
|
+
const additionalErrors = error.errors.slice(1);
|
|
150
|
+
if (additionalErrors.length > 0) {
|
|
151
|
+
const errorDetails = additionalErrors.map((err) => ` \u2022 ${err.detail || err.title || err.code}`).join("\n");
|
|
152
|
+
message += "\n\nAdditional errors:\n" + errorDetails;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (error instanceof ZapierAppNotFoundError && error.appKey) {
|
|
156
|
+
message += `
|
|
157
|
+
App key: ${error.appKey}`;
|
|
158
|
+
}
|
|
159
|
+
if (error instanceof ZapierActionError && (error.appKey || error.actionKey)) {
|
|
160
|
+
const context = [];
|
|
161
|
+
if (error.appKey) context.push(`App: ${error.appKey}`);
|
|
162
|
+
if (error.actionKey) context.push(`Action: ${error.actionKey}`);
|
|
163
|
+
message += `
|
|
164
|
+
${context.join(", ")}`;
|
|
165
|
+
}
|
|
166
|
+
if (error instanceof ZapierResourceNotFoundError && (error.resourceType || error.resourceId)) {
|
|
167
|
+
const context = [];
|
|
168
|
+
if (error.resourceType) context.push(`Type: ${error.resourceType}`);
|
|
169
|
+
if (error.resourceId) context.push(`ID: ${error.resourceId}`);
|
|
170
|
+
message += `
|
|
171
|
+
${context.join(", ")}`;
|
|
172
|
+
}
|
|
173
|
+
if (error instanceof ZapierTimeoutError && (error.attempts || error.maxAttempts)) {
|
|
174
|
+
const context = [];
|
|
175
|
+
if (error.attempts) context.push(`Attempts: ${error.attempts}`);
|
|
176
|
+
if (error.maxAttempts) context.push(`Max attempts: ${error.maxAttempts}`);
|
|
177
|
+
message += `
|
|
178
|
+
${context.join(", ")}`;
|
|
179
|
+
}
|
|
180
|
+
if (error instanceof ZapierBundleError && error.buildErrors && error.buildErrors.length > 0) {
|
|
181
|
+
message += "\n\nBuild errors:\n" + error.buildErrors.map((err) => ` \u2022 ${err}`).join("\n");
|
|
182
|
+
}
|
|
183
|
+
if (error.statusCode && !message.includes(`${error.statusCode}`)) {
|
|
184
|
+
message += `
|
|
185
|
+
HTTP Status: ${error.statusCode}`;
|
|
186
|
+
}
|
|
187
|
+
return message;
|
|
188
|
+
}
|
|
189
|
+
|
|
132
190
|
// src/plugins/apps/index.ts
|
|
133
191
|
function createActionFunction(appKey, actionType, actionKey, options, pinnedAuthId) {
|
|
134
|
-
return
|
|
192
|
+
return (actionOptions = {}) => {
|
|
135
193
|
const { sdk } = options;
|
|
136
194
|
const { inputs, authenticationId: providedAuthenticationId } = actionOptions;
|
|
137
195
|
const authenticationId = pinnedAuthId || providedAuthenticationId;
|
|
138
196
|
if (!authenticationId) {
|
|
139
|
-
throw new
|
|
197
|
+
throw new ZapierValidationError(
|
|
140
198
|
`Authentication ID is required. Either use the factory pattern: sdk.apps.${appKey}({ authenticationId }) or provide authenticationId in the action call.`
|
|
141
199
|
);
|
|
142
200
|
}
|
|
@@ -151,16 +209,16 @@ function createActionFunction(appKey, actionType, actionKey, options, pinnedAuth
|
|
|
151
209
|
}
|
|
152
210
|
function createActionTypeProxy(appKey, actionType, options, pinnedAuthId) {
|
|
153
211
|
if (actionType === "fetch") {
|
|
154
|
-
return async (
|
|
212
|
+
return async (url, init) => {
|
|
155
213
|
const { sdk } = options;
|
|
156
|
-
const authenticationId = pinnedAuthId ||
|
|
214
|
+
const authenticationId = pinnedAuthId || init?.authenticationId;
|
|
157
215
|
if (!authenticationId) {
|
|
158
|
-
throw new
|
|
216
|
+
throw new ZapierValidationError(
|
|
159
217
|
`Authentication ID is required for fetch. Either use the factory pattern: sdk.apps.${appKey}({ authenticationId }).fetch(...) or provide authenticationId in the fetch call.`
|
|
160
218
|
);
|
|
161
219
|
}
|
|
162
|
-
return sdk.fetch({
|
|
163
|
-
...
|
|
220
|
+
return sdk.fetch(url, {
|
|
221
|
+
...init,
|
|
164
222
|
authenticationId
|
|
165
223
|
});
|
|
166
224
|
};
|
|
@@ -229,18 +287,40 @@ function createAppsProxy(options) {
|
|
|
229
287
|
});
|
|
230
288
|
return appsProxy;
|
|
231
289
|
}
|
|
232
|
-
|
|
233
|
-
return
|
|
234
|
-
}
|
|
290
|
+
var appsPlugin = ({ sdk }) => {
|
|
291
|
+
return {
|
|
292
|
+
apps: createAppsProxy({ sdk })
|
|
293
|
+
};
|
|
294
|
+
};
|
|
235
295
|
|
|
236
|
-
// src/index.ts
|
|
237
|
-
|
|
296
|
+
// src/plugins/fetch/index.ts
|
|
297
|
+
var fetchPlugin = ({ sdk }) => {
|
|
298
|
+
return {
|
|
299
|
+
fetch: async function fetch(url, init) {
|
|
300
|
+
const {
|
|
301
|
+
authenticationId,
|
|
302
|
+
callbackUrl,
|
|
303
|
+
authenticationTemplate,
|
|
304
|
+
...fetchInit
|
|
305
|
+
} = init || {};
|
|
306
|
+
return sdk.request({
|
|
307
|
+
url: url.toString(),
|
|
308
|
+
method: fetchInit.method,
|
|
309
|
+
body: fetchInit.body,
|
|
310
|
+
headers: fetchInit.headers,
|
|
311
|
+
authenticationId,
|
|
312
|
+
callbackUrl,
|
|
313
|
+
authenticationTemplate
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
};
|
|
238
318
|
|
|
239
319
|
// src/resolvers/appKey.ts
|
|
240
320
|
var appKeyResolver = {
|
|
241
321
|
type: "static",
|
|
242
322
|
inputType: "text",
|
|
243
|
-
placeholder: "Enter app
|
|
323
|
+
placeholder: "Enter app key (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
244
324
|
};
|
|
245
325
|
|
|
246
326
|
// src/resolvers/actionType.ts
|
|
@@ -248,8 +328,12 @@ var actionTypeResolver = {
|
|
|
248
328
|
type: "dynamic",
|
|
249
329
|
depends: ["appKey"],
|
|
250
330
|
fetch: async (sdk, resolvedParams) => {
|
|
251
|
-
const
|
|
252
|
-
|
|
331
|
+
const actionsResponse = await sdk.listActions({
|
|
332
|
+
appKey: resolvedParams.appKey
|
|
333
|
+
});
|
|
334
|
+
const types = [
|
|
335
|
+
...new Set(actionsResponse.data.map((action) => action.action_type))
|
|
336
|
+
];
|
|
253
337
|
return types.map((type) => ({ key: type, name: type }));
|
|
254
338
|
},
|
|
255
339
|
prompt: (types) => ({
|
|
@@ -268,9 +352,11 @@ var actionKeyResolver = {
|
|
|
268
352
|
type: "dynamic",
|
|
269
353
|
depends: ["appKey", "actionType"],
|
|
270
354
|
fetch: async (sdk, resolvedParams) => {
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
355
|
+
const actionsResponse = await sdk.listActions({
|
|
356
|
+
appKey: resolvedParams.appKey
|
|
357
|
+
});
|
|
358
|
+
return actionsResponse.data.filter(
|
|
359
|
+
(action) => action.action_type === resolvedParams.actionType
|
|
274
360
|
);
|
|
275
361
|
},
|
|
276
362
|
prompt: (actions) => ({
|
|
@@ -278,7 +364,7 @@ var actionKeyResolver = {
|
|
|
278
364
|
name: "actionKey",
|
|
279
365
|
message: "Select action:",
|
|
280
366
|
choices: actions.map((action) => ({
|
|
281
|
-
name: `${action.name || action.key} - ${action.description || "No description"}`,
|
|
367
|
+
name: `${action.title || action.name || action.key} - ${action.description || "No description"}`,
|
|
282
368
|
value: action.key
|
|
283
369
|
}))
|
|
284
370
|
})
|
|
@@ -289,10 +375,19 @@ var authenticationIdResolver = {
|
|
|
289
375
|
type: "dynamic",
|
|
290
376
|
depends: ["appKey"],
|
|
291
377
|
fetch: async (sdk, resolvedParams) => {
|
|
292
|
-
|
|
378
|
+
const myAuths = await sdk.listAuthentications({
|
|
293
379
|
appKey: resolvedParams.appKey,
|
|
294
|
-
|
|
380
|
+
maxItems: 1e3,
|
|
381
|
+
owner: "me"
|
|
382
|
+
});
|
|
383
|
+
const allAuths = await sdk.listAuthentications({
|
|
384
|
+
appKey: resolvedParams.appKey,
|
|
385
|
+
maxItems: 1e3
|
|
295
386
|
});
|
|
387
|
+
const otherAuths = allAuths.data.filter(
|
|
388
|
+
(auth) => !myAuths.data.some((myAuth) => myAuth.id === auth.id)
|
|
389
|
+
);
|
|
390
|
+
return [...myAuths.data, ...otherAuths];
|
|
296
391
|
},
|
|
297
392
|
prompt: (auths, params) => ({
|
|
298
393
|
type: "list",
|
|
@@ -316,12 +411,15 @@ var inputsResolver = {
|
|
|
316
411
|
type: "fields",
|
|
317
412
|
depends: ["appKey", "actionKey", "actionType", "authenticationId"],
|
|
318
413
|
fetch: async (sdk, resolvedParams) => {
|
|
319
|
-
|
|
414
|
+
const fieldsResponse = await sdk.listInputFields({
|
|
320
415
|
appKey: resolvedParams.appKey,
|
|
321
416
|
actionKey: resolvedParams.actionKey,
|
|
322
417
|
actionType: resolvedParams.actionType,
|
|
323
|
-
authenticationId: resolvedParams.authenticationId
|
|
418
|
+
authenticationId: resolvedParams.authenticationId,
|
|
419
|
+
inputs: resolvedParams.inputs
|
|
420
|
+
// Pass along currently resolved inputs
|
|
324
421
|
});
|
|
422
|
+
return fieldsResponse.data;
|
|
325
423
|
}
|
|
326
424
|
};
|
|
327
425
|
|
|
@@ -386,8 +484,74 @@ function getResolutionOrderForParams(paramNames) {
|
|
|
386
484
|
return order;
|
|
387
485
|
}
|
|
388
486
|
|
|
389
|
-
// src/
|
|
390
|
-
|
|
487
|
+
// src/auth.ts
|
|
488
|
+
function getTokenFromEnv() {
|
|
489
|
+
return process.env.ZAPIER_TOKEN;
|
|
490
|
+
}
|
|
491
|
+
async function getTokenFromCliLogin(options = {}) {
|
|
492
|
+
try {
|
|
493
|
+
const { getToken } = await import('@zapier/zapier-sdk-cli-login');
|
|
494
|
+
return await getToken(options);
|
|
495
|
+
} catch {
|
|
496
|
+
return void 0;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
async function getTokenFromEnvOrConfig(options = {}) {
|
|
500
|
+
const envToken = getTokenFromEnv();
|
|
501
|
+
if (envToken) {
|
|
502
|
+
return envToken;
|
|
503
|
+
}
|
|
504
|
+
return getTokenFromCliLogin(options);
|
|
505
|
+
}
|
|
506
|
+
var RelayRequestSchema = z.object({
|
|
507
|
+
url: z.string().url().describe("The URL to request (will be proxied through Relay)"),
|
|
508
|
+
method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method"),
|
|
509
|
+
body: z.any().optional().describe("Request body as a string"),
|
|
510
|
+
authenticationId: z.number().int().optional().describe("Zapier authentication ID to use for the request"),
|
|
511
|
+
callbackUrl: z.string().url().optional().describe("URL to send async response to (makes request async)"),
|
|
512
|
+
authenticationTemplate: z.string().optional().describe(
|
|
513
|
+
"Optional JSON string authentication template to bypass Notary lookup"
|
|
514
|
+
),
|
|
515
|
+
headers: z.union([
|
|
516
|
+
z.record(z.string()),
|
|
517
|
+
z.instanceof(Headers),
|
|
518
|
+
z.array(z.tuple([z.string(), z.string()]))
|
|
519
|
+
]).optional().describe("Request headers")
|
|
520
|
+
}).extend({
|
|
521
|
+
relayBaseUrl: z.string().optional().describe("Base URL for Relay service")
|
|
522
|
+
}).describe("Make authenticated HTTP requests through Zapier's Relay service");
|
|
523
|
+
var RelayFetchSchema = RelayRequestSchema;
|
|
524
|
+
|
|
525
|
+
// src/plugins/registry/index.ts
|
|
526
|
+
var registryPlugin = ({ sdk, context }) => {
|
|
527
|
+
const metaKeys = Object.keys(context.meta || {});
|
|
528
|
+
const registryEntries = metaKeys.map((key) => {
|
|
529
|
+
return {
|
|
530
|
+
...context.meta[key],
|
|
531
|
+
name: key,
|
|
532
|
+
implementation: sdk[key]
|
|
533
|
+
};
|
|
534
|
+
});
|
|
535
|
+
return {
|
|
536
|
+
__registry: registryEntries
|
|
537
|
+
};
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// src/api/auth.ts
|
|
541
|
+
function isJwt(token) {
|
|
542
|
+
const parts = token.split(".");
|
|
543
|
+
if (parts.length !== 3) {
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
const base64UrlPattern = /^[A-Za-z0-9_-]+$/;
|
|
547
|
+
return parts.every((part) => part.length > 0 && base64UrlPattern.test(part));
|
|
548
|
+
}
|
|
549
|
+
function getAuthorizationHeader(token) {
|
|
550
|
+
if (isJwt(token)) {
|
|
551
|
+
return `JWT ${token}`;
|
|
552
|
+
}
|
|
553
|
+
return `Bearer ${token}`;
|
|
554
|
+
}
|
|
391
555
|
|
|
392
556
|
// src/api/debug.ts
|
|
393
557
|
function createDebugLogger(enabled) {
|
|
@@ -407,7 +571,13 @@ function createDebugFetch(options) {
|
|
|
407
571
|
const method = options2?.method || "GET";
|
|
408
572
|
debugLog(`\u2192 ${method} ${url}`, {
|
|
409
573
|
headers: options2?.headers,
|
|
410
|
-
body: options2?.body
|
|
574
|
+
body: options2?.body && typeof options2.body === "string" ? (() => {
|
|
575
|
+
try {
|
|
576
|
+
return JSON.parse(options2.body);
|
|
577
|
+
} catch {
|
|
578
|
+
return options2.body;
|
|
579
|
+
}
|
|
580
|
+
})() : options2?.body
|
|
411
581
|
});
|
|
412
582
|
try {
|
|
413
583
|
const response = await originalFetch(input, options2);
|
|
@@ -433,9 +603,7 @@ function createDebugFetch(options) {
|
|
|
433
603
|
// src/api/polling.ts
|
|
434
604
|
async function pollUntilComplete(options) {
|
|
435
605
|
const {
|
|
436
|
-
|
|
437
|
-
url,
|
|
438
|
-
headers = {},
|
|
606
|
+
fetchPoll,
|
|
439
607
|
maxAttempts = 30,
|
|
440
608
|
initialDelay = 50,
|
|
441
609
|
maxDelay = 1e3,
|
|
@@ -444,1189 +612,1360 @@ async function pollUntilComplete(options) {
|
|
|
444
612
|
resultExtractor = (response) => response
|
|
445
613
|
} = options;
|
|
446
614
|
let delay = initialDelay;
|
|
615
|
+
let errorCount = 0;
|
|
447
616
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
448
|
-
const response = await
|
|
617
|
+
const response = await fetchPoll();
|
|
449
618
|
if (response.status === successStatus) {
|
|
619
|
+
errorCount = 0;
|
|
450
620
|
const result = await response.json();
|
|
451
621
|
return resultExtractor(result);
|
|
452
622
|
} else if (response.status === pendingStatus) {
|
|
623
|
+
errorCount = 0;
|
|
453
624
|
if (attempt < maxAttempts - 1) {
|
|
454
625
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
455
626
|
delay = Math.min(delay * 2, maxDelay);
|
|
456
627
|
continue;
|
|
457
628
|
}
|
|
458
629
|
} else {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
630
|
+
errorCount++;
|
|
631
|
+
if (errorCount >= 3) {
|
|
632
|
+
throw new ZapierApiError(
|
|
633
|
+
`Poll request failed: ${response.status} ${response.statusText}`,
|
|
634
|
+
{ statusCode: response.status }
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
if (attempt < maxAttempts - 1) {
|
|
638
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
639
|
+
delay = Math.min(delay * 2, maxDelay);
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
462
642
|
}
|
|
463
643
|
}
|
|
464
|
-
throw new
|
|
644
|
+
throw new ZapierTimeoutError(
|
|
645
|
+
`Operation timed out after ${maxAttempts} attempts`,
|
|
646
|
+
{ attempts: maxAttempts, maxAttempts }
|
|
647
|
+
);
|
|
465
648
|
}
|
|
466
649
|
|
|
467
650
|
// src/api/client.ts
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
fetch
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
651
|
+
var SubdomainConfigMap = {
|
|
652
|
+
// e.g. https://relay.zapier.com
|
|
653
|
+
relay: {
|
|
654
|
+
authHeader: "X-Relay-Authorization"
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
var ZapierApiClient = class {
|
|
658
|
+
constructor(options) {
|
|
659
|
+
this.options = options;
|
|
660
|
+
this.fetch = async (path, init) => {
|
|
661
|
+
return this.plainFetch(path, init);
|
|
662
|
+
};
|
|
663
|
+
this.get = async (path, options = {}) => {
|
|
664
|
+
return this.fetchJson("GET", path, void 0, options);
|
|
665
|
+
};
|
|
666
|
+
this.post = async (path, data, options = {}) => {
|
|
667
|
+
return this.fetchJson("POST", path, data, options);
|
|
668
|
+
};
|
|
669
|
+
this.put = async (path, data, options = {}) => {
|
|
670
|
+
return this.fetchJson("PUT", path, data, options);
|
|
671
|
+
};
|
|
672
|
+
this.delete = async (path, options = {}) => {
|
|
673
|
+
return this.fetchJson("DELETE", path, void 0, options);
|
|
674
|
+
};
|
|
675
|
+
this.poll = async (path, options = {}) => {
|
|
676
|
+
return pollUntilComplete({
|
|
677
|
+
fetchPoll: () => this.plainFetch(path, {
|
|
678
|
+
method: "GET",
|
|
679
|
+
searchParams: options.searchParams,
|
|
680
|
+
authRequired: options.authRequired
|
|
681
|
+
}),
|
|
682
|
+
maxAttempts: options.maxAttempts,
|
|
683
|
+
initialDelay: options.initialDelay,
|
|
684
|
+
maxDelay: options.maxDelay,
|
|
685
|
+
successStatus: options.successStatus,
|
|
686
|
+
pendingStatus: options.pendingStatus,
|
|
687
|
+
resultExtractor: options.resultExtractor
|
|
496
688
|
});
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
// Helper to parse response data
|
|
692
|
+
async parseResult(response) {
|
|
693
|
+
try {
|
|
694
|
+
return { type: "json", data: await response.json() };
|
|
695
|
+
} catch {
|
|
696
|
+
return { type: "text", data: await response.text() };
|
|
497
697
|
}
|
|
498
|
-
return url.toString();
|
|
499
698
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (!resolvedToken) {
|
|
510
|
-
resolvedToken = await getTokenFromEnvOrConfig({
|
|
511
|
-
onEvent,
|
|
512
|
-
fetch: originalFetch
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
if (resolvedToken) {
|
|
516
|
-
headers.Authorization = getAuthorizationHeader(resolvedToken);
|
|
699
|
+
// Helper to get a token from the different places it could be gotten
|
|
700
|
+
async getAuthToken() {
|
|
701
|
+
if (this.options.token) {
|
|
702
|
+
return this.options.token;
|
|
703
|
+
}
|
|
704
|
+
if (this.options.getToken) {
|
|
705
|
+
const token = await this.options.getToken();
|
|
706
|
+
if (token) {
|
|
707
|
+
return token;
|
|
517
708
|
}
|
|
518
709
|
}
|
|
519
|
-
return
|
|
710
|
+
return getTokenFromEnvOrConfig({
|
|
711
|
+
onEvent: this.options.onEvent,
|
|
712
|
+
fetch: this.options.fetch
|
|
713
|
+
});
|
|
520
714
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
715
|
+
// Helper to handle responses
|
|
716
|
+
async handleResponse(params) {
|
|
717
|
+
const { response, customErrorHandler, wasMissingAuthToken } = params;
|
|
718
|
+
const { data: responseData } = await this.parseResult(response);
|
|
719
|
+
if (response.ok) {
|
|
720
|
+
return responseData;
|
|
721
|
+
}
|
|
722
|
+
const errorInfo = {
|
|
723
|
+
status: response.status,
|
|
724
|
+
statusText: response.statusText,
|
|
725
|
+
data: responseData
|
|
726
|
+
};
|
|
727
|
+
if (customErrorHandler) {
|
|
728
|
+
const customError = customErrorHandler(errorInfo);
|
|
729
|
+
if (customError) {
|
|
730
|
+
if (customError instanceof Error) {
|
|
526
731
|
throw customError;
|
|
732
|
+
} else {
|
|
733
|
+
throw new Error(
|
|
734
|
+
`customErrorHandler returned a non-Error: ${JSON.stringify(customError)}`
|
|
735
|
+
);
|
|
527
736
|
}
|
|
528
737
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
738
|
+
}
|
|
739
|
+
const { message, errors } = this.parseErrorResponse(errorInfo);
|
|
740
|
+
const errorOptions = {
|
|
741
|
+
statusCode: response.status,
|
|
742
|
+
errors
|
|
743
|
+
};
|
|
744
|
+
if (response.status === 404) {
|
|
745
|
+
throw new ZapierNotFoundError(message, errorOptions);
|
|
746
|
+
}
|
|
747
|
+
if (response.status === 401 || response.status === 403) {
|
|
748
|
+
if (wasMissingAuthToken) {
|
|
749
|
+
throw new ZapierAuthenticationError(
|
|
750
|
+
`Authentication required (HTTP ${response.status}). Please provide a token in options or set ZAPIER_TOKEN environment variable.`,
|
|
751
|
+
errorOptions
|
|
532
752
|
);
|
|
533
753
|
}
|
|
534
|
-
throw new
|
|
754
|
+
throw new ZapierAuthenticationError(message, errorOptions);
|
|
755
|
+
}
|
|
756
|
+
if (response.status === 400) {
|
|
757
|
+
throw new ZapierValidationError(message, errorOptions);
|
|
758
|
+
}
|
|
759
|
+
throw new ZapierApiError(message, errorOptions);
|
|
760
|
+
}
|
|
761
|
+
hasErrorArray(data) {
|
|
762
|
+
return typeof data === "object" && data !== null && "errors" in data && Array.isArray(data.errors);
|
|
763
|
+
}
|
|
764
|
+
// Helper to check if data has API errors
|
|
765
|
+
isApiErrorArray(dataArray) {
|
|
766
|
+
const data = dataArray[0];
|
|
767
|
+
return typeof data === "object" && data !== null && "message" in data && "code" in data && "title" in data && "detail" in data;
|
|
768
|
+
}
|
|
769
|
+
// Do our best to extract an error message from the response data
|
|
770
|
+
extractErrorMessage(data) {
|
|
771
|
+
if (typeof data === "string") {
|
|
772
|
+
return data;
|
|
773
|
+
}
|
|
774
|
+
if (typeof data === "object" && data !== null) {
|
|
775
|
+
if ("message" in data && typeof data.message === "string") {
|
|
776
|
+
return data.message;
|
|
777
|
+
}
|
|
778
|
+
if ("error" in data) {
|
|
779
|
+
if (typeof data.error === "string") {
|
|
780
|
+
return data.error;
|
|
781
|
+
}
|
|
782
|
+
if (typeof data.error === "object" && data.error !== null) {
|
|
783
|
+
if ("message" in data.error && typeof data.error.message === "string") {
|
|
784
|
+
return data.error.message;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
try {
|
|
788
|
+
return JSON.stringify(data.error);
|
|
789
|
+
} catch {
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if ("errors" in data && Array.isArray(data.errors)) {
|
|
793
|
+
if (this.isApiErrorArray(data.errors)) {
|
|
794
|
+
return data.errors[0].detail || data.errors[0].title;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
535
797
|
}
|
|
798
|
+
return void 0;
|
|
799
|
+
}
|
|
800
|
+
// Helper to parse API error response
|
|
801
|
+
parseErrorResponse(errorInfo) {
|
|
802
|
+
const fallbackMessage = `HTTP ${errorInfo.status}: ${errorInfo.statusText}`;
|
|
536
803
|
try {
|
|
537
|
-
|
|
804
|
+
if (typeof errorInfo.data === "string") {
|
|
805
|
+
return { message: `${fallbackMessage}: ${errorInfo.data}` };
|
|
806
|
+
}
|
|
807
|
+
const errorMessage = this.extractErrorMessage(errorInfo.data) || fallbackMessage;
|
|
808
|
+
if (this.hasErrorArray(errorInfo.data)) {
|
|
809
|
+
if (this.isApiErrorArray(errorInfo.data.errors)) {
|
|
810
|
+
return {
|
|
811
|
+
message: errorMessage,
|
|
812
|
+
errors: errorInfo.data.errors
|
|
813
|
+
};
|
|
814
|
+
} else {
|
|
815
|
+
return {
|
|
816
|
+
message: errorMessage,
|
|
817
|
+
errors: errorInfo.data.errors.map((e) => ({
|
|
818
|
+
status: errorInfo.status,
|
|
819
|
+
code: String(errorInfo.status),
|
|
820
|
+
title: errorInfo.statusText,
|
|
821
|
+
detail: JSON.stringify(e)
|
|
822
|
+
}))
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return { message: errorMessage };
|
|
538
827
|
} catch {
|
|
539
|
-
return
|
|
828
|
+
return { message: fallbackMessage };
|
|
540
829
|
}
|
|
541
830
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
const
|
|
546
|
-
|
|
547
|
-
|
|
831
|
+
// Check if this is a path that needs subdomain routing
|
|
832
|
+
// e.g. /relay/workflows -> relay.zapier.com/workflows
|
|
833
|
+
applySubdomainBehavior(path) {
|
|
834
|
+
const pathSegments = path.split("/").filter(Boolean);
|
|
835
|
+
if (pathSegments.length > 0 && pathSegments[0] in SubdomainConfigMap) {
|
|
836
|
+
const domainPrefix = pathSegments[0];
|
|
837
|
+
const subdomainConfig = SubdomainConfigMap[domainPrefix];
|
|
838
|
+
const originalBaseUrl = new URL(this.options.baseUrl);
|
|
839
|
+
const finalBaseUrl = `https://${domainPrefix}.${originalBaseUrl.hostname}`;
|
|
840
|
+
const pathWithoutPrefix = "/" + pathSegments.slice(1).join("/");
|
|
841
|
+
return { url: new URL(pathWithoutPrefix, finalBaseUrl), subdomainConfig };
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
url: new URL(path, this.options.baseUrl),
|
|
845
|
+
subdomainConfig: void 0
|
|
548
846
|
};
|
|
549
|
-
return await fetch2(url, {
|
|
550
|
-
...init,
|
|
551
|
-
headers: finalHeaders
|
|
552
|
-
});
|
|
553
847
|
}
|
|
554
|
-
|
|
555
|
-
|
|
848
|
+
// Helper to build full URLs and return routing info
|
|
849
|
+
buildUrl(path, searchParams) {
|
|
850
|
+
const { url, subdomainConfig } = this.applySubdomainBehavior(path);
|
|
851
|
+
if (searchParams) {
|
|
852
|
+
Object.entries(searchParams).forEach(([key, value]) => {
|
|
853
|
+
url.searchParams.set(key, value);
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
return { url: url.toString(), subdomainConfig };
|
|
857
|
+
}
|
|
858
|
+
// Helper to build headers
|
|
859
|
+
async buildHeaders(options = {}, subdomainConfig) {
|
|
860
|
+
const headers = new Headers(options.headers ?? {});
|
|
861
|
+
const authToken = await this.getAuthToken();
|
|
862
|
+
if (authToken) {
|
|
863
|
+
const authHeaderName = subdomainConfig?.authHeader || "Authorization";
|
|
864
|
+
headers.set(authHeaderName, getAuthorizationHeader(authToken));
|
|
865
|
+
}
|
|
866
|
+
if (options.authRequired) {
|
|
867
|
+
if (headers.get("Authorization") == null && authToken == null) {
|
|
868
|
+
throw new ZapierAuthenticationError(
|
|
869
|
+
`Authentication required but no token available. Please set ZAPIER_TOKEN, or run the 'login' command with the CLI.`
|
|
870
|
+
);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return headers;
|
|
874
|
+
}
|
|
875
|
+
// Helper to perform HTTP requests with JSON handling
|
|
876
|
+
async fetchJson(method, path, data, options = {}) {
|
|
877
|
+
const headers = { ...options.headers };
|
|
556
878
|
if (data && typeof data === "object") {
|
|
557
879
|
headers["Content-Type"] = "application/json";
|
|
558
880
|
}
|
|
559
|
-
const
|
|
881
|
+
const wasMissingAuthToken = options.authRequired && await this.getAuthToken() == null;
|
|
882
|
+
const response = await this.plainFetch(path, {
|
|
883
|
+
...options,
|
|
560
884
|
method,
|
|
561
|
-
body: data ? JSON.stringify(data) : void 0,
|
|
562
|
-
headers
|
|
563
|
-
searchParams: options2.searchParams,
|
|
564
|
-
authRequired: options2.authRequired,
|
|
565
|
-
customErrorHandler: options2.customErrorHandler
|
|
885
|
+
body: data != null ? JSON.stringify(data) : void 0,
|
|
886
|
+
headers
|
|
566
887
|
});
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
},
|
|
577
|
-
async put(path, data, options2 = {}) {
|
|
578
|
-
return fetchJson("PUT", path, data, options2);
|
|
579
|
-
},
|
|
580
|
-
async delete(path, options2 = {}) {
|
|
581
|
-
return fetchJson("DELETE", path, void 0, options2);
|
|
582
|
-
},
|
|
583
|
-
async poll(path, options2 = {}) {
|
|
584
|
-
const url = buildUrl(path, options2.searchParams);
|
|
585
|
-
const headers = await buildHeaders(options2);
|
|
586
|
-
return pollUntilComplete({
|
|
587
|
-
fetch: fetch2,
|
|
588
|
-
url,
|
|
589
|
-
headers,
|
|
590
|
-
maxAttempts: options2.maxAttempts,
|
|
591
|
-
initialDelay: options2.initialDelay,
|
|
592
|
-
maxDelay: options2.maxDelay,
|
|
593
|
-
successStatus: options2.successStatus,
|
|
594
|
-
pendingStatus: options2.pendingStatus,
|
|
595
|
-
resultExtractor: options2.resultExtractor
|
|
596
|
-
});
|
|
597
|
-
},
|
|
598
|
-
async fetch(input, init) {
|
|
599
|
-
return plainFetch(input, init);
|
|
888
|
+
const result = await this.handleResponse({
|
|
889
|
+
response,
|
|
890
|
+
customErrorHandler: options.customErrorHandler,
|
|
891
|
+
wasMissingAuthToken
|
|
892
|
+
});
|
|
893
|
+
if (typeof result === "string") {
|
|
894
|
+
throw new ZapierValidationError(
|
|
895
|
+
`Response could not be parsed as JSON: ${result}`
|
|
896
|
+
);
|
|
600
897
|
}
|
|
601
|
-
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// src/api/index.ts
|
|
605
|
-
function generateRequestId() {
|
|
606
|
-
return Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
607
|
-
}
|
|
608
|
-
function getOrCreateApiClient(config) {
|
|
609
|
-
const {
|
|
610
|
-
baseUrl = "https://zapier.com",
|
|
611
|
-
token,
|
|
612
|
-
getToken,
|
|
613
|
-
api: providedApi,
|
|
614
|
-
debug = false,
|
|
615
|
-
fetch: customFetch
|
|
616
|
-
} = config;
|
|
617
|
-
if (providedApi) {
|
|
618
|
-
return providedApi;
|
|
898
|
+
return result;
|
|
619
899
|
}
|
|
620
|
-
|
|
900
|
+
// Plain fetch method for API paths (must start with /)
|
|
901
|
+
async plainFetch(path, fetchOptions) {
|
|
902
|
+
if (!path.startsWith("/")) {
|
|
903
|
+
throw new ZapierValidationError(
|
|
904
|
+
`plainFetch expects a path starting with '/', got: ${path}`
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
if (fetchOptions?.body && typeof fetchOptions.body === "object") {
|
|
908
|
+
fetchOptions.body = JSON.stringify(fetchOptions.body);
|
|
909
|
+
}
|
|
910
|
+
const { url, subdomainConfig } = this.buildUrl(
|
|
911
|
+
path,
|
|
912
|
+
fetchOptions?.searchParams
|
|
913
|
+
);
|
|
914
|
+
const builtHeaders = await this.buildHeaders(
|
|
915
|
+
fetchOptions,
|
|
916
|
+
subdomainConfig
|
|
917
|
+
);
|
|
918
|
+
const inputHeaders = new Headers(fetchOptions?.headers ?? {});
|
|
919
|
+
const mergedHeaders = new Headers();
|
|
920
|
+
builtHeaders.forEach((value, key) => {
|
|
921
|
+
mergedHeaders.set(key, value);
|
|
922
|
+
});
|
|
923
|
+
inputHeaders.forEach((value, key) => {
|
|
924
|
+
mergedHeaders.set(key, value);
|
|
925
|
+
});
|
|
926
|
+
return await this.options.fetch(url, {
|
|
927
|
+
...fetchOptions,
|
|
928
|
+
headers: mergedHeaders
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
var createZapierApi = (options) => {
|
|
933
|
+
const {
|
|
934
|
+
baseUrl,
|
|
935
|
+
token,
|
|
936
|
+
getToken,
|
|
937
|
+
debug = false,
|
|
938
|
+
fetch: originalFetch = globalThis.fetch,
|
|
939
|
+
onEvent
|
|
940
|
+
} = options;
|
|
941
|
+
const debugLog = createDebugLogger(debug);
|
|
942
|
+
const debugFetch = createDebugFetch({ originalFetch, debugLog });
|
|
943
|
+
return new ZapierApiClient({
|
|
621
944
|
baseUrl,
|
|
622
945
|
token,
|
|
623
946
|
getToken,
|
|
624
947
|
debug,
|
|
625
|
-
fetch:
|
|
948
|
+
fetch: debugFetch,
|
|
949
|
+
onEvent
|
|
626
950
|
});
|
|
627
|
-
}
|
|
951
|
+
};
|
|
628
952
|
|
|
629
|
-
// src/
|
|
630
|
-
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
953
|
+
// src/plugins/api/index.ts
|
|
954
|
+
var apiPlugin = (params) => {
|
|
955
|
+
const {
|
|
956
|
+
fetch: customFetch = globalThis.fetch,
|
|
957
|
+
baseUrl = "https://zapier.com",
|
|
958
|
+
token,
|
|
959
|
+
getToken,
|
|
960
|
+
onEvent,
|
|
961
|
+
debug = false
|
|
962
|
+
} = params;
|
|
963
|
+
const api = createZapierApi({
|
|
964
|
+
baseUrl,
|
|
965
|
+
token,
|
|
966
|
+
getToken,
|
|
967
|
+
debug,
|
|
968
|
+
fetch: customFetch,
|
|
969
|
+
onEvent
|
|
640
970
|
});
|
|
641
971
|
return {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
category: app.category?.name,
|
|
647
|
-
actions: [],
|
|
648
|
-
triggers: [],
|
|
649
|
-
current_implementation_id: app.current_implementation_id
|
|
972
|
+
context: {
|
|
973
|
+
api
|
|
974
|
+
// Provide API client in context for other plugins to use
|
|
975
|
+
}
|
|
650
976
|
};
|
|
651
|
-
}
|
|
977
|
+
};
|
|
652
978
|
|
|
653
|
-
// src/
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
token: options2.token,
|
|
664
|
-
baseUrl: options2.baseUrl,
|
|
665
|
-
debug: options2.debug,
|
|
666
|
-
fetch: options2.fetch
|
|
667
|
-
});
|
|
668
|
-
const selectedApi = app.current_implementation_id;
|
|
669
|
-
if (selectedApi) {
|
|
670
|
-
const versionlessApi = selectedApi.split("@")[0];
|
|
671
|
-
searchParams.versionless_selected_api = versionlessApi;
|
|
672
|
-
}
|
|
673
|
-
} catch (error) {
|
|
674
|
-
if (error instanceof Error && error.name === "AppNotFoundError") {
|
|
675
|
-
throw error;
|
|
676
|
-
}
|
|
677
|
-
console.warn(
|
|
678
|
-
`Warning: Could not filter by app ${options2.appKey}:`,
|
|
679
|
-
error instanceof Error ? error.message : "Unknown error"
|
|
680
|
-
);
|
|
681
|
-
}
|
|
979
|
+
// src/utils/pagination-utils.ts
|
|
980
|
+
var offsetCursorMarker = "$$offset$$";
|
|
981
|
+
function splitOffsetCursor(cursor) {
|
|
982
|
+
if (!cursor) {
|
|
983
|
+
return [0, cursor];
|
|
984
|
+
}
|
|
985
|
+
try {
|
|
986
|
+
const parsedCursor = JSON.parse(cursor);
|
|
987
|
+
if (!Array.isArray(parsedCursor)) {
|
|
988
|
+
return [0, cursor];
|
|
682
989
|
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
searchParams.search = options2.title;
|
|
990
|
+
const [marker, offset, currentCursor] = parsedCursor;
|
|
991
|
+
if (marker !== offsetCursorMarker) {
|
|
992
|
+
return [0, cursor];
|
|
687
993
|
}
|
|
688
|
-
if (
|
|
689
|
-
|
|
994
|
+
if (typeof offset !== "number") {
|
|
995
|
+
return [0, cursor];
|
|
690
996
|
}
|
|
691
|
-
|
|
692
|
-
|
|
997
|
+
return [offset, currentCursor];
|
|
998
|
+
} catch {
|
|
999
|
+
return [0, cursor];
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function createOffsetCursor(offset, currentCursor) {
|
|
1003
|
+
return JSON.stringify([offsetCursorMarker, offset, currentCursor]);
|
|
1004
|
+
}
|
|
1005
|
+
async function* paginateMaxItems(pageFunction, pageOptions) {
|
|
1006
|
+
let cursor = pageOptions?.cursor;
|
|
1007
|
+
let totalItemsYielded = 0;
|
|
1008
|
+
const maxItems = pageOptions?.maxItems;
|
|
1009
|
+
const pageSize = pageOptions?.pageSize;
|
|
1010
|
+
do {
|
|
1011
|
+
const options = {
|
|
1012
|
+
...pageOptions || {},
|
|
1013
|
+
cursor,
|
|
1014
|
+
pageSize: maxItems !== void 0 && pageSize !== void 0 ? Math.min(pageSize, maxItems) : pageSize
|
|
1015
|
+
};
|
|
1016
|
+
const page = await pageFunction(options);
|
|
1017
|
+
if (maxItems !== void 0) {
|
|
1018
|
+
const remainingItems = maxItems - totalItemsYielded;
|
|
1019
|
+
if (page.data.length >= remainingItems) {
|
|
1020
|
+
const yieldedPage = {
|
|
1021
|
+
...page,
|
|
1022
|
+
data: page.data.slice(0, remainingItems),
|
|
1023
|
+
nextCursor: void 0
|
|
1024
|
+
};
|
|
1025
|
+
yield yieldedPage;
|
|
1026
|
+
break;
|
|
1027
|
+
}
|
|
693
1028
|
}
|
|
694
|
-
|
|
695
|
-
|
|
1029
|
+
yield page;
|
|
1030
|
+
totalItemsYielded += page.data.length;
|
|
1031
|
+
cursor = page.nextCursor;
|
|
1032
|
+
} while (cursor);
|
|
1033
|
+
}
|
|
1034
|
+
async function* paginateBuffered(pageFunction, pageOptions) {
|
|
1035
|
+
const pageSize = pageOptions?.pageSize;
|
|
1036
|
+
const [cursorOffset, currentCursor] = splitOffsetCursor(pageOptions?.cursor);
|
|
1037
|
+
const options = {
|
|
1038
|
+
...pageOptions || {},
|
|
1039
|
+
cursor: currentCursor
|
|
1040
|
+
};
|
|
1041
|
+
const iterator = paginateMaxItems(pageFunction, options);
|
|
1042
|
+
let bufferedPages = [];
|
|
1043
|
+
let isFirstPage = true;
|
|
1044
|
+
let cursor;
|
|
1045
|
+
for await (let page of iterator) {
|
|
1046
|
+
if (isFirstPage) {
|
|
1047
|
+
isFirstPage = false;
|
|
1048
|
+
if (cursorOffset) {
|
|
1049
|
+
page = {
|
|
1050
|
+
...page,
|
|
1051
|
+
data: page.data.slice(cursorOffset)
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
696
1054
|
}
|
|
697
|
-
if (
|
|
698
|
-
|
|
1055
|
+
if (!pageSize) {
|
|
1056
|
+
yield page;
|
|
1057
|
+
cursor = page.nextCursor;
|
|
1058
|
+
continue;
|
|
699
1059
|
}
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
searchParams,
|
|
704
|
-
customErrorHandler: (response) => {
|
|
705
|
-
if (response.status === 401) {
|
|
706
|
-
return new Error(
|
|
707
|
-
`Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${response.status})`
|
|
708
|
-
);
|
|
709
|
-
}
|
|
710
|
-
if (response.status === 403) {
|
|
711
|
-
return new Error(
|
|
712
|
-
`Access forbidden. Your token may not have the required scopes to list authentications. (HTTP ${response.status})`
|
|
713
|
-
);
|
|
714
|
-
}
|
|
715
|
-
return void 0;
|
|
716
|
-
}
|
|
717
|
-
}
|
|
1060
|
+
const bufferedLength = bufferedPages.reduce(
|
|
1061
|
+
(acc, page2) => acc + page2.data.length,
|
|
1062
|
+
0
|
|
718
1063
|
);
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
previousUrl: data.previous
|
|
1064
|
+
if (bufferedLength + page.data.length < pageSize) {
|
|
1065
|
+
bufferedPages.push(page);
|
|
1066
|
+
cursor = page.nextCursor;
|
|
1067
|
+
continue;
|
|
1068
|
+
}
|
|
1069
|
+
const bufferedItems = bufferedPages.map((p) => p.data).flat();
|
|
1070
|
+
const allItems = [...bufferedItems, ...page.data];
|
|
1071
|
+
const pageItems = allItems.slice(0, pageSize);
|
|
1072
|
+
const remainingItems = allItems.slice(pageItems.length);
|
|
1073
|
+
if (remainingItems.length === 0) {
|
|
1074
|
+
yield {
|
|
1075
|
+
...page,
|
|
1076
|
+
data: pageItems,
|
|
1077
|
+
nextCursor: page.nextCursor
|
|
734
1078
|
};
|
|
1079
|
+
bufferedPages = [];
|
|
1080
|
+
cursor = page.nextCursor;
|
|
1081
|
+
continue;
|
|
735
1082
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1083
|
+
yield {
|
|
1084
|
+
...page,
|
|
1085
|
+
data: pageItems,
|
|
1086
|
+
nextCursor: createOffsetCursor(
|
|
1087
|
+
page.data.length - remainingItems.length,
|
|
1088
|
+
cursor
|
|
1089
|
+
)
|
|
1090
|
+
};
|
|
1091
|
+
while (remainingItems.length > pageSize) {
|
|
1092
|
+
const pageItems2 = remainingItems.splice(0, pageSize);
|
|
1093
|
+
yield {
|
|
1094
|
+
...page,
|
|
1095
|
+
data: pageItems2,
|
|
1096
|
+
nextCursor: createOffsetCursor(
|
|
1097
|
+
page.data.length - remainingItems.length,
|
|
1098
|
+
cursor
|
|
1099
|
+
)
|
|
1100
|
+
};
|
|
745
1101
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
1102
|
+
bufferedPages = [
|
|
1103
|
+
{
|
|
1104
|
+
...page,
|
|
1105
|
+
data: remainingItems
|
|
1106
|
+
}
|
|
1107
|
+
];
|
|
1108
|
+
cursor = page.nextCursor;
|
|
1109
|
+
}
|
|
1110
|
+
if (bufferedPages.length > 0) {
|
|
1111
|
+
const lastBufferedPage = bufferedPages.slice(-1)[0];
|
|
1112
|
+
const bufferedItems = bufferedPages.map((p) => p.data).flat();
|
|
1113
|
+
yield {
|
|
1114
|
+
...lastBufferedPage,
|
|
1115
|
+
data: bufferedItems
|
|
1116
|
+
};
|
|
756
1117
|
}
|
|
757
|
-
return listAuthenticationsInternal(options);
|
|
758
1118
|
}
|
|
1119
|
+
var paginate = paginateBuffered;
|
|
759
1120
|
|
|
760
|
-
// src/
|
|
761
|
-
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
return new Error(
|
|
775
|
-
`Access forbidden. Your token may not have the required scopes to get authentication ${authenticationId}. (HTTP ${response.status})`
|
|
776
|
-
);
|
|
777
|
-
}
|
|
778
|
-
if (response.status === 404) {
|
|
779
|
-
return new Error(
|
|
780
|
-
`Authentication ${authenticationId} not found. It may not exist or you may not have access to it. (HTTP ${response.status})`
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
return void 0;
|
|
1121
|
+
// src/utils/validation.ts
|
|
1122
|
+
var validate = (schema, input) => {
|
|
1123
|
+
const result = schema.safeParse(input);
|
|
1124
|
+
if (!result.success) {
|
|
1125
|
+
const errorMessages = result.error.errors.map((error) => {
|
|
1126
|
+
const path = error.path.length > 0 ? error.path.join(".") : "input";
|
|
1127
|
+
return `${path}: ${error.message}`;
|
|
1128
|
+
});
|
|
1129
|
+
const message = `Validation failed:
|
|
1130
|
+
${errorMessages.join("\n ")}`;
|
|
1131
|
+
throw new ZapierValidationError(message, {
|
|
1132
|
+
details: {
|
|
1133
|
+
zodErrors: result.error.errors,
|
|
1134
|
+
input
|
|
784
1135
|
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
return
|
|
788
|
-
|
|
789
|
-
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
return result.data;
|
|
1139
|
+
};
|
|
1140
|
+
function createValidator(schema) {
|
|
1141
|
+
return function validateFn(input) {
|
|
1142
|
+
return validate(schema, input);
|
|
790
1143
|
};
|
|
791
1144
|
}
|
|
1145
|
+
var validateOptions = (schema, options) => {
|
|
1146
|
+
return validate(schema, options);
|
|
1147
|
+
};
|
|
792
1148
|
|
|
793
|
-
// src/
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
limit: 1
|
|
798
|
-
});
|
|
799
|
-
return auths.length > 0 ? auths[0] : null;
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// src/functions/findUniqueAuthentication/index.ts
|
|
803
|
-
async function findUniqueAuthentication(options = {}) {
|
|
804
|
-
const auths = await listAuthentications({
|
|
805
|
-
...options,
|
|
806
|
-
limit: 2
|
|
807
|
-
// Get up to 2 to check for uniqueness
|
|
808
|
-
});
|
|
809
|
-
if (auths.length === 0) {
|
|
810
|
-
throw new Error("No authentication found matching the specified criteria");
|
|
1149
|
+
// src/utils/function-utils.ts
|
|
1150
|
+
function extractCursor(data) {
|
|
1151
|
+
if (!data?.next) {
|
|
1152
|
+
return void 0;
|
|
811
1153
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
1154
|
+
try {
|
|
1155
|
+
const urlObj = new URL(data.next);
|
|
1156
|
+
const offset = urlObj.searchParams.get("offset");
|
|
1157
|
+
return offset || void 0;
|
|
1158
|
+
} catch {
|
|
1159
|
+
return void 0;
|
|
816
1160
|
}
|
|
817
|
-
return auths[0];
|
|
818
1161
|
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
const api = getOrCreateApiClient(options);
|
|
823
|
-
const searchParams = {};
|
|
824
|
-
if (options.category) {
|
|
825
|
-
searchParams.category = options.category;
|
|
826
|
-
}
|
|
827
|
-
if (options.limit) {
|
|
828
|
-
searchParams.limit = options.limit.toString();
|
|
829
|
-
}
|
|
830
|
-
if (options.offset) {
|
|
831
|
-
searchParams.offset = options.offset.toString();
|
|
832
|
-
}
|
|
833
|
-
const data = await api.get("/api/v4/apps/", { searchParams });
|
|
834
|
-
const apps = data.results?.map(
|
|
835
|
-
(app) => ({
|
|
836
|
-
key: app.slug,
|
|
837
|
-
name: app.name,
|
|
838
|
-
description: app.description,
|
|
839
|
-
version: "1.0.0",
|
|
840
|
-
// API doesn't provide version
|
|
841
|
-
category: app.category?.name,
|
|
842
|
-
actions: [],
|
|
843
|
-
// Will be populated separately
|
|
844
|
-
triggers: [],
|
|
845
|
-
current_implementation_id: app.current_implementation_id
|
|
846
|
-
})
|
|
847
|
-
) || [];
|
|
848
|
-
if (apps.length > 0) {
|
|
849
|
-
apps.__pagination = {
|
|
850
|
-
count: data.count,
|
|
851
|
-
hasNext: !!data.next,
|
|
852
|
-
hasPrevious: !!data.previous,
|
|
853
|
-
nextUrl: data.next,
|
|
854
|
-
previousUrl: data.previous
|
|
855
|
-
};
|
|
1162
|
+
function normalizeError(error) {
|
|
1163
|
+
if (error instanceof ZapierError) {
|
|
1164
|
+
return error;
|
|
856
1165
|
}
|
|
857
|
-
|
|
1166
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1167
|
+
return new ZapierUnknownError(`Unknown error: ${message}`, { cause: error });
|
|
858
1168
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
fetch: options.fetch
|
|
872
|
-
});
|
|
873
|
-
const implementationId = appData.current_implementation_id?.split("@")[0];
|
|
874
|
-
if (!implementationId) {
|
|
875
|
-
throw new Error("No current_implementation_id found for app");
|
|
876
|
-
}
|
|
877
|
-
const searchParams2 = {
|
|
878
|
-
global: "true",
|
|
879
|
-
public_only: "true",
|
|
880
|
-
selected_apis: implementationId
|
|
881
|
-
};
|
|
882
|
-
const data2 = await api.get("/api/v4/implementations/", {
|
|
883
|
-
searchParams: searchParams2
|
|
884
|
-
});
|
|
885
|
-
const actions2 = [];
|
|
886
|
-
for (const implementation of data2.results || []) {
|
|
887
|
-
if (implementation.actions) {
|
|
888
|
-
for (const action of implementation.actions) {
|
|
889
|
-
const transformedAction = {
|
|
890
|
-
key: action.key,
|
|
891
|
-
name: action.name || action.label,
|
|
892
|
-
description: action.description || "",
|
|
893
|
-
appKey: implementation.slug || "",
|
|
894
|
-
type: action.type || action.type_of || "read",
|
|
895
|
-
inputFields: [],
|
|
896
|
-
// Would need additional API call for detailed fields
|
|
897
|
-
outputFields: []
|
|
898
|
-
};
|
|
899
|
-
if (options?.type && transformedAction.type !== options.type) {
|
|
900
|
-
continue;
|
|
901
|
-
}
|
|
902
|
-
actions2.push(transformedAction);
|
|
903
|
-
}
|
|
1169
|
+
function createFunction(coreFn, schema) {
|
|
1170
|
+
const functionName = coreFn.name;
|
|
1171
|
+
const namedFunctions = {
|
|
1172
|
+
[functionName]: async function(options) {
|
|
1173
|
+
try {
|
|
1174
|
+
const normalizedOptions = options ?? {};
|
|
1175
|
+
if (schema) {
|
|
1176
|
+
const validatedOptions = validateOptions(schema, normalizedOptions);
|
|
1177
|
+
return await coreFn({
|
|
1178
|
+
...normalizedOptions,
|
|
1179
|
+
...validatedOptions
|
|
1180
|
+
});
|
|
904
1181
|
}
|
|
1182
|
+
return await coreFn(normalizedOptions);
|
|
1183
|
+
} catch (error) {
|
|
1184
|
+
throw normalizeError(error);
|
|
905
1185
|
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1186
|
+
}
|
|
1187
|
+
};
|
|
1188
|
+
return namedFunctions[functionName];
|
|
1189
|
+
}
|
|
1190
|
+
function createPageFunction(coreFn) {
|
|
1191
|
+
const functionName = coreFn.name + "Page";
|
|
1192
|
+
const namedFunctions = {
|
|
1193
|
+
[functionName]: async function(options) {
|
|
1194
|
+
try {
|
|
1195
|
+
const result = await coreFn(options);
|
|
1196
|
+
if (result && typeof result === "object" && "data" in result) {
|
|
1197
|
+
const data = result.data;
|
|
1198
|
+
return {
|
|
1199
|
+
data: Array.isArray(data) ? data : [data],
|
|
1200
|
+
nextCursor: result.nextCursor
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
if (Array.isArray(result)) {
|
|
1204
|
+
return { data: result };
|
|
1205
|
+
}
|
|
1206
|
+
return { data: [result] };
|
|
1207
|
+
} catch (error) {
|
|
1208
|
+
throw normalizeError(error);
|
|
919
1209
|
}
|
|
920
|
-
console.warn(
|
|
921
|
-
"Optimized app lookup failed, falling back to full scan:",
|
|
922
|
-
error
|
|
923
|
-
);
|
|
924
1210
|
}
|
|
925
|
-
}
|
|
926
|
-
const searchParams = {
|
|
927
|
-
global: "true",
|
|
928
|
-
public_only: "true"
|
|
929
1211
|
};
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1212
|
+
return namedFunctions[functionName];
|
|
1213
|
+
}
|
|
1214
|
+
function createPaginatedFunction(coreFn, schema) {
|
|
1215
|
+
const pageFunction = createPageFunction(coreFn);
|
|
1216
|
+
const functionName = coreFn.name;
|
|
1217
|
+
const validator = schema ? createValidator(schema) : null;
|
|
1218
|
+
const namedFunctions = {
|
|
1219
|
+
[functionName]: function(options) {
|
|
1220
|
+
const normalizedOptions = options ?? {};
|
|
1221
|
+
const validatedOptions = {
|
|
1222
|
+
...normalizedOptions,
|
|
1223
|
+
...validator ? validator(normalizedOptions) : normalizedOptions
|
|
1224
|
+
};
|
|
1225
|
+
const pageSize = validatedOptions.pageSize || 100;
|
|
1226
|
+
const optimizedOptions = {
|
|
1227
|
+
...validatedOptions,
|
|
1228
|
+
pageSize
|
|
1229
|
+
};
|
|
1230
|
+
const iterator = paginate(pageFunction, optimizedOptions);
|
|
1231
|
+
const firstPagePromise = iterator.next().then((result) => {
|
|
1232
|
+
if (result.done) {
|
|
1233
|
+
throw new Error("Paginate should always iterate at least once");
|
|
947
1234
|
}
|
|
948
|
-
|
|
949
|
-
|
|
1235
|
+
return result.value;
|
|
1236
|
+
});
|
|
1237
|
+
return Object.assign(firstPagePromise, {
|
|
1238
|
+
[Symbol.asyncIterator]: async function* () {
|
|
1239
|
+
yield await firstPagePromise;
|
|
1240
|
+
for await (const page of iterator) {
|
|
1241
|
+
yield page;
|
|
1242
|
+
}
|
|
1243
|
+
},
|
|
1244
|
+
items: function() {
|
|
1245
|
+
return {
|
|
1246
|
+
[Symbol.asyncIterator]: async function* () {
|
|
1247
|
+
const firstPage = await firstPagePromise;
|
|
1248
|
+
for (const item of firstPage.data) {
|
|
1249
|
+
yield item;
|
|
1250
|
+
}
|
|
1251
|
+
for await (const page of iterator) {
|
|
1252
|
+
for (const item of page.data) {
|
|
1253
|
+
yield item;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
950
1258
|
}
|
|
951
|
-
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
return namedFunctions[functionName];
|
|
1263
|
+
}
|
|
1264
|
+
var NeedChoicesSchema = z.object({
|
|
1265
|
+
key: z.string().optional(),
|
|
1266
|
+
label: z.string().optional(),
|
|
1267
|
+
sample: z.string().optional(),
|
|
1268
|
+
value: z.string().optional()
|
|
1269
|
+
});
|
|
1270
|
+
var NeedSchema = z.object({
|
|
1271
|
+
key: z.string(),
|
|
1272
|
+
alters_custom_fields: z.boolean().nullable().optional(),
|
|
1273
|
+
capabilities: z.array(z.string()).optional(),
|
|
1274
|
+
choices: z.array(NeedChoicesSchema).optional(),
|
|
1275
|
+
computed: z.boolean().nullable().optional(),
|
|
1276
|
+
custom_field: z.boolean().optional(),
|
|
1277
|
+
default: z.string().optional(),
|
|
1278
|
+
depends_on: z.array(z.string()).optional(),
|
|
1279
|
+
format: z.literal("SELECT").optional(),
|
|
1280
|
+
from_search: z.boolean().optional(),
|
|
1281
|
+
from_write: z.boolean().optional(),
|
|
1282
|
+
help_text: z.string().optional(),
|
|
1283
|
+
help_text_html: z.string().optional(),
|
|
1284
|
+
input_format: z.array(z.string()).optional(),
|
|
1285
|
+
label: z.string().optional(),
|
|
1286
|
+
language: z.string().optional(),
|
|
1287
|
+
parent_key: z.string().optional(),
|
|
1288
|
+
placeholder: z.string().optional(),
|
|
1289
|
+
prefill: z.string().optional(),
|
|
1290
|
+
required: z.boolean().optional(),
|
|
1291
|
+
searchfill: z.string().optional(),
|
|
1292
|
+
send_in_json: z.boolean().optional(),
|
|
1293
|
+
regex: z.string().optional(),
|
|
1294
|
+
type: z.enum([
|
|
1295
|
+
"integer",
|
|
1296
|
+
"string",
|
|
1297
|
+
"text",
|
|
1298
|
+
"datetime",
|
|
1299
|
+
"boolean",
|
|
1300
|
+
"file",
|
|
1301
|
+
"decimal",
|
|
1302
|
+
"copy",
|
|
1303
|
+
"password",
|
|
1304
|
+
"dict",
|
|
1305
|
+
"code",
|
|
1306
|
+
"filter",
|
|
1307
|
+
"json"
|
|
1308
|
+
]).optional(),
|
|
1309
|
+
list: z.boolean().optional()
|
|
1310
|
+
});
|
|
1311
|
+
var ActionLinksSchema = z.object({
|
|
1312
|
+
action_url: z.string().optional()
|
|
1313
|
+
});
|
|
1314
|
+
var ActionPermissionsSchema = z.object({
|
|
1315
|
+
can_use: z.boolean().optional()
|
|
1316
|
+
});
|
|
1317
|
+
var ActionSchema = z.object({
|
|
1318
|
+
id: z.string().optional(),
|
|
1319
|
+
type: z.enum([
|
|
1320
|
+
"filter",
|
|
1321
|
+
"read",
|
|
1322
|
+
"read_bulk",
|
|
1323
|
+
"run",
|
|
1324
|
+
"search",
|
|
1325
|
+
"search_and_write",
|
|
1326
|
+
"search_or_write",
|
|
1327
|
+
"write"
|
|
1328
|
+
]),
|
|
1329
|
+
key: z.string(),
|
|
1330
|
+
name: z.string(),
|
|
1331
|
+
noun: z.string().optional(),
|
|
1332
|
+
description: z.string(),
|
|
1333
|
+
description_html: z.string().optional(),
|
|
1334
|
+
is_important: z.boolean().optional(),
|
|
1335
|
+
is_hidden: z.boolean().optional(),
|
|
1336
|
+
needs: z.array(NeedSchema).optional(),
|
|
1337
|
+
meta: z.string().optional(),
|
|
1338
|
+
selected_api: z.string().optional(),
|
|
1339
|
+
links: ActionLinksSchema.optional(),
|
|
1340
|
+
permissions: ActionPermissionsSchema.optional()
|
|
1341
|
+
});
|
|
1342
|
+
var ChoiceSchema = z.object({
|
|
1343
|
+
value: z.union([z.string(), z.number()]),
|
|
1344
|
+
label: z.string()
|
|
1345
|
+
});
|
|
1346
|
+
z.object({
|
|
1347
|
+
key: z.string(),
|
|
1348
|
+
label: z.string(),
|
|
1349
|
+
type: z.enum([
|
|
1350
|
+
"string",
|
|
1351
|
+
"number",
|
|
1352
|
+
"boolean",
|
|
1353
|
+
"datetime",
|
|
1354
|
+
"file",
|
|
1355
|
+
"object",
|
|
1356
|
+
"array"
|
|
1357
|
+
]),
|
|
1358
|
+
required: z.boolean(),
|
|
1359
|
+
description: z.string().optional(),
|
|
1360
|
+
choices: z.array(ChoiceSchema).optional()
|
|
1361
|
+
});
|
|
1362
|
+
z.object({
|
|
1363
|
+
data: z.array(z.any())
|
|
1364
|
+
});
|
|
1365
|
+
var ActionFieldChoiceSchema = z.object({
|
|
1366
|
+
value: z.union([z.string(), z.number()]),
|
|
1367
|
+
label: z.string()
|
|
1368
|
+
});
|
|
1369
|
+
z.object({
|
|
1370
|
+
key: z.string(),
|
|
1371
|
+
label: z.string().optional(),
|
|
1372
|
+
required: z.boolean(),
|
|
1373
|
+
type: z.string().optional(),
|
|
1374
|
+
helpText: z.string().optional(),
|
|
1375
|
+
helpTextHtml: z.string().optional(),
|
|
1376
|
+
choices: z.array(ActionFieldChoiceSchema).optional(),
|
|
1377
|
+
default: z.string().optional(),
|
|
1378
|
+
placeholder: z.string().optional(),
|
|
1379
|
+
computed: z.boolean().optional(),
|
|
1380
|
+
customField: z.boolean().optional(),
|
|
1381
|
+
dependsOn: z.array(z.string()).optional(),
|
|
1382
|
+
format: z.string().optional(),
|
|
1383
|
+
inputFormat: z.array(z.string()).optional()
|
|
1384
|
+
});
|
|
1385
|
+
var AuthenticationSchema = z.object({
|
|
1386
|
+
id: z.number(),
|
|
1387
|
+
date: z.string(),
|
|
1388
|
+
lastchanged: z.string().optional(),
|
|
1389
|
+
account_id: z.number(),
|
|
1390
|
+
customuser_id: z.number().optional(),
|
|
1391
|
+
selected_api: z.string(),
|
|
1392
|
+
destination_selected_api: z.string().nullable().optional(),
|
|
1393
|
+
is_invite_only: z.boolean(),
|
|
1394
|
+
is_private: z.boolean(),
|
|
1395
|
+
shared_with_all: z.boolean(),
|
|
1396
|
+
is_stale: z.string().optional(),
|
|
1397
|
+
is_shared: z.string().optional(),
|
|
1398
|
+
marked_stale_at: z.string().nullable().optional(),
|
|
1399
|
+
label: z.string().nullable().optional(),
|
|
1400
|
+
identifier: z.string().nullable().optional(),
|
|
1401
|
+
title: z.string().nullable().optional(),
|
|
1402
|
+
url: z.string().optional(),
|
|
1403
|
+
groups: z.string().optional(),
|
|
1404
|
+
members: z.string().optional(),
|
|
1405
|
+
permissions: z.record(z.boolean()).optional()
|
|
1406
|
+
});
|
|
1407
|
+
z.object({
|
|
1408
|
+
count: z.number(),
|
|
1409
|
+
next: z.string().nullable().optional(),
|
|
1410
|
+
previous: z.string().nullable().optional(),
|
|
1411
|
+
results: z.array(AuthenticationSchema)
|
|
1412
|
+
});
|
|
1413
|
+
var UserProfileSchema = z.object({
|
|
1414
|
+
id: z.number(),
|
|
1415
|
+
code: z.string(),
|
|
1416
|
+
user_id: z.number(),
|
|
1417
|
+
auto_provisioned: z.boolean(),
|
|
1418
|
+
first_name: z.string(),
|
|
1419
|
+
last_name: z.string(),
|
|
1420
|
+
username: z.string(),
|
|
1421
|
+
personas: z.string(),
|
|
1422
|
+
user_generated_personas: z.string(),
|
|
1423
|
+
last_login: z.string(),
|
|
1424
|
+
email: z.string(),
|
|
1425
|
+
email_hash: z.string(),
|
|
1426
|
+
email_confirmed: z.boolean(),
|
|
1427
|
+
timezone: z.string(),
|
|
1428
|
+
photo_url: z.string(),
|
|
1429
|
+
has_seen_notifications: z.record(z.boolean().nullable()),
|
|
1430
|
+
signup: z.string(),
|
|
1431
|
+
since_signup: z.string(),
|
|
1432
|
+
has_activated: z.boolean(),
|
|
1433
|
+
enable_gz_creator: z.boolean(),
|
|
1434
|
+
should_see_nps_survey: z.boolean(),
|
|
1435
|
+
is_developer: z.boolean(),
|
|
1436
|
+
is_expert: z.boolean(),
|
|
1437
|
+
tos_agreement: z.boolean(),
|
|
1438
|
+
should_renew_tos: z.boolean(),
|
|
1439
|
+
is_gdpr_consented: z.boolean(),
|
|
1440
|
+
disable_ssl_check: z.boolean(),
|
|
1441
|
+
identity: z.number(),
|
|
1442
|
+
summary_schedule: z.string(),
|
|
1443
|
+
alert_triggers: z.string(),
|
|
1444
|
+
alert_actions: z.string(),
|
|
1445
|
+
is_staff: z.boolean(),
|
|
1446
|
+
is_zt_reviewer: z.boolean(),
|
|
1447
|
+
is_high_value: z.boolean(),
|
|
1448
|
+
is_temporary: z.boolean(),
|
|
1449
|
+
banner_message: z.string(),
|
|
1450
|
+
enable_totp_2fa: z.boolean(),
|
|
1451
|
+
viewed_help: z.record(z.boolean()),
|
|
1452
|
+
show_editor_migration_mesaging: z.boolean(),
|
|
1453
|
+
switches: z.record(z.any()),
|
|
1454
|
+
organizations: z.array(z.any().nullable()),
|
|
1455
|
+
primary_organization: z.any().nullable(),
|
|
1456
|
+
has_active_zaps: z.boolean(),
|
|
1457
|
+
has_google_sso: z.boolean(),
|
|
1458
|
+
auth_realm: z.string(),
|
|
1459
|
+
roles: z.array(
|
|
1460
|
+
z.object({
|
|
1461
|
+
account_id: z.number(),
|
|
1462
|
+
role: z.string()
|
|
1463
|
+
})
|
|
1464
|
+
)
|
|
1465
|
+
});
|
|
1466
|
+
z.object({
|
|
1467
|
+
age_in_days: z.string().optional(),
|
|
1468
|
+
api_docs_url: z.string().nullable().optional(),
|
|
1469
|
+
app_profile_url: z.string(),
|
|
1470
|
+
banner: z.string().optional(),
|
|
1471
|
+
categories: z.array(z.any()).optional(),
|
|
1472
|
+
// TODO: Define proper service_category type
|
|
1473
|
+
canonical_id: z.string().optional(),
|
|
1474
|
+
current_implementation_id: z.string(),
|
|
1475
|
+
days_since_last_update: z.string().optional(),
|
|
1476
|
+
description: z.string(),
|
|
1477
|
+
external_url: z.string(),
|
|
1478
|
+
hashtag: z.string().optional(),
|
|
1479
|
+
id: z.number().optional(),
|
|
1480
|
+
image: z.string().optional(),
|
|
1481
|
+
images: z.string().optional(),
|
|
1482
|
+
integration_overview_html: z.string().nullable().optional(),
|
|
1483
|
+
internal_id: z.string(),
|
|
1484
|
+
invite_url: z.string().nullable().optional(),
|
|
1485
|
+
is_beta: z.string().optional(),
|
|
1486
|
+
is_built_in: z.string().optional(),
|
|
1487
|
+
is_featured: z.string().optional(),
|
|
1488
|
+
is_premium: z.boolean().optional(),
|
|
1489
|
+
is_public: z.string().optional(),
|
|
1490
|
+
is_upcoming: z.string().optional(),
|
|
1491
|
+
learn_more_url: z.string(),
|
|
1492
|
+
name: z.string(),
|
|
1493
|
+
popularity: z.number(),
|
|
1494
|
+
primary_color: z.string(),
|
|
1495
|
+
request_count: z.string().optional(),
|
|
1496
|
+
slug: z.string(),
|
|
1497
|
+
zap_usage_count: z.number().nullable().optional()
|
|
1498
|
+
});
|
|
1499
|
+
var ServiceSchema = z.object({
|
|
1500
|
+
id: z.number().optional(),
|
|
1501
|
+
canonical_id: z.string().optional(),
|
|
1502
|
+
current_implementation_id: z.string(),
|
|
1503
|
+
name: z.string(),
|
|
1504
|
+
slug: z.string(),
|
|
1505
|
+
app_url: z.string().optional(),
|
|
1506
|
+
learn_more_url: z.string().optional(),
|
|
1507
|
+
description: z.string(),
|
|
1508
|
+
primary_color: z.string(),
|
|
1509
|
+
popularity: z.number(),
|
|
1510
|
+
image: z.string().optional(),
|
|
1511
|
+
images: z.string().optional()
|
|
1512
|
+
});
|
|
1513
|
+
z.object({
|
|
1514
|
+
results: z.array(ServiceSchema),
|
|
1515
|
+
next: z.string().nullable().optional(),
|
|
1516
|
+
previous: z.string().nullable().optional()
|
|
1517
|
+
});
|
|
1518
|
+
z.object({
|
|
1519
|
+
selected_api: z.string(),
|
|
1520
|
+
action: z.string(),
|
|
1521
|
+
type_of: z.string(),
|
|
1522
|
+
authentication_id: z.number().optional(),
|
|
1523
|
+
params: z.record(z.any()).optional()
|
|
1524
|
+
});
|
|
1525
|
+
z.object({
|
|
1526
|
+
success: z.boolean(),
|
|
1527
|
+
needs: z.array(NeedSchema).optional(),
|
|
1528
|
+
errors: z.array(z.string()).optional(),
|
|
1529
|
+
last_fetched_at: z.string().optional()
|
|
1530
|
+
});
|
|
1531
|
+
var ImplementationSchema = z.object({
|
|
1532
|
+
selected_api: z.string(),
|
|
1533
|
+
app_id: z.number().optional(),
|
|
1534
|
+
auth_type: z.string().optional(),
|
|
1535
|
+
auth_fields: z.string().optional(),
|
|
1536
|
+
actions: z.array(ActionSchema).optional(),
|
|
1537
|
+
is_deprecated: z.boolean().optional(),
|
|
1538
|
+
is_private_only: z.boolean().optional(),
|
|
1539
|
+
is_invite_only: z.boolean().optional(),
|
|
1540
|
+
is_beta: z.boolean().optional().default(false),
|
|
1541
|
+
is_premium: z.boolean().optional().default(false),
|
|
1542
|
+
is_hidden: z.string().optional(),
|
|
1543
|
+
name: z.string().optional(),
|
|
1544
|
+
slug: z.string().optional(),
|
|
1545
|
+
images: z.record(z.string().nullable()).optional(),
|
|
1546
|
+
primary_color: z.string().optional(),
|
|
1547
|
+
secondary_color: z.string().optional(),
|
|
1548
|
+
current_implementation: z.string().optional(),
|
|
1549
|
+
other_implementations: z.string().optional()
|
|
1550
|
+
});
|
|
1551
|
+
z.object({
|
|
1552
|
+
count: z.number(),
|
|
1553
|
+
next: z.string().nullable().optional(),
|
|
1554
|
+
previous: z.string().nullable().optional(),
|
|
1555
|
+
results: z.array(ImplementationSchema)
|
|
1556
|
+
});
|
|
1557
|
+
var ImplementationMetaSchema = z.object({
|
|
1558
|
+
id: z.string(),
|
|
1559
|
+
// e.g. "ZapierFormatterCLIAPI@1.0.7"
|
|
1560
|
+
name: z.string(),
|
|
1561
|
+
slug: z.string(),
|
|
1562
|
+
images: z.object({
|
|
1563
|
+
url_16x16: z.string().optional(),
|
|
1564
|
+
url_32x32: z.string().optional(),
|
|
1565
|
+
url_64x64: z.string().optional(),
|
|
1566
|
+
url_128x128: z.string().optional()
|
|
1567
|
+
}).optional(),
|
|
1568
|
+
// Include other fields for completeness but we'll only use what we need
|
|
1569
|
+
ageInDays: z.union([z.string(), z.number()]).optional(),
|
|
1570
|
+
authType: z.string().nullable().optional(),
|
|
1571
|
+
banner: z.string().optional(),
|
|
1572
|
+
categories: z.array(
|
|
1573
|
+
z.object({
|
|
1574
|
+
id: z.number(),
|
|
1575
|
+
name: z.string(),
|
|
1576
|
+
slug: z.string()
|
|
1577
|
+
})
|
|
1578
|
+
).optional(),
|
|
1579
|
+
isBeta: z.boolean().optional(),
|
|
1580
|
+
isBuiltIn: z.boolean().optional(),
|
|
1581
|
+
isDeprecated: z.boolean().optional(),
|
|
1582
|
+
isFeatured: z.boolean().optional(),
|
|
1583
|
+
isHidden: z.boolean().optional(),
|
|
1584
|
+
isInvite: z.boolean().optional(),
|
|
1585
|
+
isPremium: z.boolean().optional(),
|
|
1586
|
+
isPublic: z.boolean().optional(),
|
|
1587
|
+
isUpcoming: z.boolean().optional(),
|
|
1588
|
+
popularity: z.number().optional(),
|
|
1589
|
+
apiDocsUrl: z.string().optional(),
|
|
1590
|
+
classification: z.string().optional()
|
|
1591
|
+
});
|
|
1592
|
+
z.object({
|
|
1593
|
+
count: z.number(),
|
|
1594
|
+
next: z.string().nullable().optional(),
|
|
1595
|
+
previous: z.string().nullable().optional(),
|
|
1596
|
+
results: z.array(ImplementationMetaSchema)
|
|
1597
|
+
});
|
|
1598
|
+
|
|
1599
|
+
// src/schemas/UserProfile.ts
|
|
1600
|
+
var UserProfileItemSchema = withFormatter(
|
|
1601
|
+
UserProfileSchema.omit({ user_id: true }).extend({
|
|
1602
|
+
full_name: z.string()
|
|
1603
|
+
// Computed field: first_name + " " + last_name
|
|
1604
|
+
}),
|
|
1605
|
+
{
|
|
1606
|
+
format: (item) => {
|
|
1607
|
+
const details = [];
|
|
1608
|
+
details.push({ text: item.email, style: "dim" });
|
|
1609
|
+
if (item.timezone) {
|
|
1610
|
+
details.push({
|
|
1611
|
+
text: `Timezone: ${item.timezone}`,
|
|
1612
|
+
style: "accent"
|
|
1613
|
+
});
|
|
952
1614
|
}
|
|
1615
|
+
details.push({
|
|
1616
|
+
text: `Member since: ${item.since_signup}`,
|
|
1617
|
+
style: "dim"
|
|
1618
|
+
});
|
|
1619
|
+
return {
|
|
1620
|
+
title: item.full_name,
|
|
1621
|
+
subtitle: `@${item.username}`,
|
|
1622
|
+
details
|
|
1623
|
+
};
|
|
953
1624
|
}
|
|
954
1625
|
}
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1626
|
+
);
|
|
1627
|
+
|
|
1628
|
+
// src/plugins/getProfile/schemas.ts
|
|
1629
|
+
var GetProfileSchema = withOutputSchema(
|
|
1630
|
+
z.object({}).optional().describe("Get current user's profile information"),
|
|
1631
|
+
UserProfileItemSchema
|
|
1632
|
+
);
|
|
1633
|
+
|
|
1634
|
+
// src/plugins/getProfile/index.ts
|
|
1635
|
+
var getProfilePlugin = ({ context }) => {
|
|
1636
|
+
const getProfile = createFunction(async function getProfile2() {
|
|
1637
|
+
const profile = await context.api.get("/api/v4/profile/", {
|
|
1638
|
+
authRequired: true
|
|
1639
|
+
});
|
|
1640
|
+
const { user_id: _unusedUserId, ...data } = profile;
|
|
1641
|
+
return {
|
|
1642
|
+
data: {
|
|
1643
|
+
...data,
|
|
1644
|
+
// Pass through all API response fields
|
|
1645
|
+
full_name: `${profile.first_name} ${profile.last_name}`
|
|
1646
|
+
// Computed field
|
|
1647
|
+
}
|
|
962
1648
|
};
|
|
1649
|
+
}, GetProfileSchema);
|
|
1650
|
+
return {
|
|
1651
|
+
getProfile,
|
|
1652
|
+
context: {
|
|
1653
|
+
meta: {
|
|
1654
|
+
getProfile: {
|
|
1655
|
+
inputSchema: GetProfileSchema
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
};
|
|
1660
|
+
};
|
|
1661
|
+
var AppItemSchema = withFormatter(
|
|
1662
|
+
z.object({
|
|
1663
|
+
// Essential properties only
|
|
1664
|
+
title: z.string(),
|
|
1665
|
+
// Mapped from name
|
|
1666
|
+
key: z.string(),
|
|
1667
|
+
// Mapped from selected_api
|
|
1668
|
+
current_implementation_id: z.string(),
|
|
1669
|
+
// From id, keeps the full version
|
|
1670
|
+
version: z.string().optional(),
|
|
1671
|
+
// Extracted from implementation ID
|
|
1672
|
+
description: z.string().optional(),
|
|
1673
|
+
slug: z.string().optional()
|
|
1674
|
+
}),
|
|
1675
|
+
{
|
|
1676
|
+
format: (item) => {
|
|
1677
|
+
return {
|
|
1678
|
+
title: item.title,
|
|
1679
|
+
subtitle: `(${item.key})`,
|
|
1680
|
+
details: []
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
963
1683
|
}
|
|
964
|
-
|
|
965
|
-
}
|
|
1684
|
+
);
|
|
966
1685
|
|
|
967
|
-
// src/
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
(
|
|
976
|
-
)
|
|
977
|
-
|
|
978
|
-
|
|
1686
|
+
// src/plugins/listApps/schemas.ts
|
|
1687
|
+
var ListAppsSchema = withOutputSchema(
|
|
1688
|
+
z.object({
|
|
1689
|
+
appKeys: z.array(z.string()).optional().describe(
|
|
1690
|
+
"Filter apps by app keys (e.g., 'SlackCLIAPI' or slug like 'github')"
|
|
1691
|
+
),
|
|
1692
|
+
search: z.string().optional().describe("Search for apps by name"),
|
|
1693
|
+
pageSize: z.number().min(1).optional().describe("Number of apps per page"),
|
|
1694
|
+
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
|
|
1695
|
+
}).describe("List all available apps with optional filtering"),
|
|
1696
|
+
AppItemSchema
|
|
1697
|
+
);
|
|
1698
|
+
|
|
1699
|
+
// src/utils/domain-utils.ts
|
|
1700
|
+
function splitVersionedKey(versionedKey) {
|
|
1701
|
+
const parts = versionedKey.split("@");
|
|
1702
|
+
if (parts.length >= 2) {
|
|
1703
|
+
const baseKey = parts[0];
|
|
1704
|
+
const version = parts.slice(1).join("@");
|
|
1705
|
+
return [baseKey, version];
|
|
979
1706
|
}
|
|
980
|
-
return
|
|
1707
|
+
return [versionedKey, void 0];
|
|
981
1708
|
}
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
throw new Error(
|
|
1001
|
-
`Action type mismatch: expected ${actionType}, got ${actionData.type}`
|
|
1709
|
+
function normalizeImplementationMetaToAppItem(implementationMeta) {
|
|
1710
|
+
const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
|
|
1711
|
+
return {
|
|
1712
|
+
title: implementationMeta.name,
|
|
1713
|
+
key: selectedApi,
|
|
1714
|
+
current_implementation_id: implementationMeta.id,
|
|
1715
|
+
// Keep the full versioned ID
|
|
1716
|
+
version: appVersion,
|
|
1717
|
+
// Extract version separately
|
|
1718
|
+
slug: implementationMeta.slug
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
function normalizeAuthenticationItem(auth, options = {}) {
|
|
1722
|
+
let appKey = options.app_key;
|
|
1723
|
+
let version = options.version;
|
|
1724
|
+
if (auth.selected_api) {
|
|
1725
|
+
const [extractedAppKey, extractedVersion] = splitVersionedKey(
|
|
1726
|
+
auth.selected_api
|
|
1002
1727
|
);
|
|
1728
|
+
if (!appKey) {
|
|
1729
|
+
appKey = extractedAppKey;
|
|
1730
|
+
}
|
|
1731
|
+
if (!version) {
|
|
1732
|
+
version = extractedVersion;
|
|
1733
|
+
}
|
|
1003
1734
|
}
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
actionType: actionData.type,
|
|
1010
|
-
executionOptions: { inputs: inputs || {} },
|
|
1011
|
-
authenticationId: providedAuthenticationId,
|
|
1012
|
-
options
|
|
1013
|
-
});
|
|
1014
|
-
const executionTime = Date.now() - startTime;
|
|
1735
|
+
const {
|
|
1736
|
+
selected_api: selectedApi,
|
|
1737
|
+
customuser_id: userId,
|
|
1738
|
+
...restOfAuth
|
|
1739
|
+
} = auth;
|
|
1015
1740
|
return {
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1741
|
+
...restOfAuth,
|
|
1742
|
+
// Pass through all other API response fields except selected_api
|
|
1743
|
+
implementation_id: selectedApi,
|
|
1744
|
+
// Rename selected_api to implementation_id
|
|
1745
|
+
title: auth.title || auth.label || void 0,
|
|
1746
|
+
// Coerce title from label if missing
|
|
1747
|
+
is_expired: auth.is_stale,
|
|
1748
|
+
// Map is_stale to is_expired
|
|
1749
|
+
expired_at: auth.marked_stale_at,
|
|
1750
|
+
// Map marked_stale_at to expired_at
|
|
1751
|
+
app_key: appKey,
|
|
1752
|
+
// App key from implementations endpoint or parsed from selected_api
|
|
1753
|
+
version,
|
|
1754
|
+
// Version from selected_api or provided
|
|
1755
|
+
user_id: userId
|
|
1756
|
+
// Map customuser_id to user_id
|
|
1022
1757
|
};
|
|
1023
1758
|
}
|
|
1024
|
-
|
|
1025
|
-
const {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
} = actionOptions;
|
|
1034
|
-
const appData = await getApp({
|
|
1035
|
-
appKey: appSlug,
|
|
1036
|
-
api,
|
|
1037
|
-
token: options.token,
|
|
1038
|
-
baseUrl: options.baseUrl,
|
|
1039
|
-
debug: options.debug,
|
|
1040
|
-
fetch: options.fetch
|
|
1041
|
-
});
|
|
1042
|
-
const selectedApi = appData.current_implementation_id;
|
|
1043
|
-
if (!selectedApi) {
|
|
1044
|
-
throw new Error("No current_implementation_id found for app");
|
|
1045
|
-
}
|
|
1046
|
-
const runRequest = {
|
|
1047
|
-
data: {
|
|
1048
|
-
authentication_id: authenticationId || 1,
|
|
1049
|
-
selected_api: selectedApi,
|
|
1050
|
-
action_key: actionKey,
|
|
1051
|
-
action_type: actionType,
|
|
1052
|
-
inputs: executionOptions.inputs || {}
|
|
1053
|
-
}
|
|
1759
|
+
function normalizeActionItem(action) {
|
|
1760
|
+
const { name, type, selected_api: appKey, ...restOfAction } = action;
|
|
1761
|
+
return {
|
|
1762
|
+
...restOfAction,
|
|
1763
|
+
app_key: appKey || "",
|
|
1764
|
+
action_type: type,
|
|
1765
|
+
title: name,
|
|
1766
|
+
// Map name to title
|
|
1767
|
+
type: "action"
|
|
1054
1768
|
};
|
|
1055
|
-
const runData = await api.post("/api/actions/v1/runs", runRequest);
|
|
1056
|
-
const runId = runData.data.id;
|
|
1057
|
-
return await api.poll(`/api/actions/v1/runs/${runId}`, {
|
|
1058
|
-
successStatus: 200,
|
|
1059
|
-
pendingStatus: 202,
|
|
1060
|
-
resultExtractor: (result) => result.data
|
|
1061
|
-
});
|
|
1062
1769
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
const { appKey, actionKey, actionType, authenticationId, params } = options;
|
|
1068
|
-
const appData = await getApp({
|
|
1069
|
-
appKey,
|
|
1070
|
-
api,
|
|
1071
|
-
token: options.token,
|
|
1072
|
-
baseUrl: options.baseUrl,
|
|
1073
|
-
debug: options.debug,
|
|
1074
|
-
fetch: options.fetch
|
|
1075
|
-
});
|
|
1076
|
-
const selectedApi = appData.current_implementation_id;
|
|
1077
|
-
if (!selectedApi) {
|
|
1078
|
-
throw new Error("No current_implementation_id found for app");
|
|
1079
|
-
}
|
|
1080
|
-
const needsRequest = {
|
|
1081
|
-
selected_api: selectedApi,
|
|
1082
|
-
action: actionKey,
|
|
1083
|
-
type_of: actionType,
|
|
1084
|
-
authentication_id: authenticationId,
|
|
1085
|
-
params: params || {}
|
|
1770
|
+
function groupVersionedAppKeysByType(appKeys) {
|
|
1771
|
+
const result = {
|
|
1772
|
+
selectedApi: [],
|
|
1773
|
+
slug: []
|
|
1086
1774
|
};
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
choices: need.choices?.map((choice) => ({
|
|
1104
|
-
value: choice.value,
|
|
1105
|
-
label: choice.label
|
|
1106
|
-
})),
|
|
1107
|
-
default: need.default,
|
|
1108
|
-
placeholder: need.placeholder,
|
|
1109
|
-
computed: need.computed,
|
|
1110
|
-
customField: need.custom_field,
|
|
1111
|
-
dependsOn: need.depends_on,
|
|
1112
|
-
format: need.format,
|
|
1113
|
-
inputFormat: need.input_format
|
|
1114
|
-
}));
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
// src/functions/generateTypes/index.ts
|
|
1118
|
-
function generateFetchMethodSignature() {
|
|
1119
|
-
return ` /** Make authenticated HTTP requests through Zapier's Relay service */
|
|
1120
|
-
fetch: (options: Omit<z.infer<typeof RelayFetchSchema>, 'authenticationId'>) => Promise<Response>`;
|
|
1121
|
-
}
|
|
1122
|
-
async function generateTypes(options) {
|
|
1123
|
-
const {
|
|
1124
|
-
appKey,
|
|
1125
|
-
authenticationId,
|
|
1126
|
-
output = `./types/${appKey}.d.ts`
|
|
1127
|
-
} = options;
|
|
1128
|
-
const { app, version } = parseAppIdentifier(appKey);
|
|
1129
|
-
const actions = await listActions({
|
|
1130
|
-
...options,
|
|
1131
|
-
appKey: app
|
|
1132
|
-
});
|
|
1133
|
-
if (actions.length === 0) {
|
|
1134
|
-
const typeDefinitions2 = generateEmptyTypesFile(app, version);
|
|
1135
|
-
if (output) {
|
|
1136
|
-
const fs = await import('fs');
|
|
1137
|
-
const path = await import('path');
|
|
1138
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
1139
|
-
fs.writeFileSync(output, typeDefinitions2, "utf8");
|
|
1140
|
-
}
|
|
1141
|
-
return typeDefinitions2;
|
|
1142
|
-
}
|
|
1143
|
-
const actionsWithFields = [];
|
|
1144
|
-
if (authenticationId) {
|
|
1145
|
-
for (const action of actions) {
|
|
1146
|
-
try {
|
|
1147
|
-
const fields = await listFields({
|
|
1148
|
-
...options,
|
|
1149
|
-
appKey: action.appKey,
|
|
1150
|
-
actionKey: action.key,
|
|
1151
|
-
actionType: action.type,
|
|
1152
|
-
authenticationId
|
|
1153
|
-
});
|
|
1154
|
-
actionsWithFields.push({ ...action, inputFields: fields });
|
|
1155
|
-
} catch {
|
|
1156
|
-
actionsWithFields.push({ ...action, inputFields: [] });
|
|
1775
|
+
const seenSelectedApi = /* @__PURE__ */ new Set();
|
|
1776
|
+
const seenSlugs = /* @__PURE__ */ new Set();
|
|
1777
|
+
for (const key of appKeys) {
|
|
1778
|
+
const [keyWithoutVersion, version] = splitVersionedKey(key);
|
|
1779
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1780
|
+
if (uuidRegex.test(keyWithoutVersion)) {
|
|
1781
|
+
throw new Error(
|
|
1782
|
+
`UUID app keys are not supported. Use app slug or implementation ID instead of: ${key}`
|
|
1783
|
+
);
|
|
1784
|
+
}
|
|
1785
|
+
if (isSnakeCasedSlug(keyWithoutVersion)) {
|
|
1786
|
+
const dashified = dashifySnakeCasedSlug(keyWithoutVersion);
|
|
1787
|
+
const slugWithVersion = version ? `${dashified}@${version}` : dashified;
|
|
1788
|
+
if (!seenSlugs.has(slugWithVersion)) {
|
|
1789
|
+
seenSlugs.add(slugWithVersion);
|
|
1790
|
+
result.slug.push(slugWithVersion);
|
|
1157
1791
|
}
|
|
1792
|
+
continue;
|
|
1793
|
+
}
|
|
1794
|
+
if (keyWithoutVersion.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/)) {
|
|
1795
|
+
seenSlugs.add(key);
|
|
1796
|
+
result.slug.push(key);
|
|
1797
|
+
continue;
|
|
1798
|
+
}
|
|
1799
|
+
if (!seenSelectedApi.has(key)) {
|
|
1800
|
+
seenSelectedApi.add(key);
|
|
1801
|
+
result.selectedApi.push(key);
|
|
1158
1802
|
}
|
|
1159
|
-
} else {
|
|
1160
|
-
actions.forEach((action) => {
|
|
1161
|
-
actionsWithFields.push({ ...action, inputFields: [] });
|
|
1162
|
-
});
|
|
1163
|
-
}
|
|
1164
|
-
const typeDefinitions = generateTypeDefinitions(
|
|
1165
|
-
app,
|
|
1166
|
-
actionsWithFields,
|
|
1167
|
-
version
|
|
1168
|
-
);
|
|
1169
|
-
if (output) {
|
|
1170
|
-
const fs = await import('fs');
|
|
1171
|
-
const path = await import('path');
|
|
1172
|
-
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
1173
|
-
fs.writeFileSync(output, typeDefinitions, "utf8");
|
|
1174
1803
|
}
|
|
1175
|
-
return
|
|
1804
|
+
return result;
|
|
1176
1805
|
}
|
|
1177
|
-
function
|
|
1178
|
-
const
|
|
1806
|
+
function groupAppKeysByType(appKeys) {
|
|
1807
|
+
const grouped = groupVersionedAppKeysByType(appKeys);
|
|
1179
1808
|
return {
|
|
1180
|
-
|
|
1181
|
-
|
|
1809
|
+
selectedApi: [
|
|
1810
|
+
...new Set(grouped.selectedApi.map((key) => key.split("@")[0]))
|
|
1811
|
+
],
|
|
1812
|
+
slug: [...new Set(grouped.slug.map((key) => key.split("@")[0]))]
|
|
1182
1813
|
};
|
|
1183
1814
|
}
|
|
1184
|
-
function
|
|
1185
|
-
if (
|
|
1186
|
-
|
|
1815
|
+
function isSnakeCasedSlug(slug) {
|
|
1816
|
+
if (slug.match(/^_[0-9]/)) {
|
|
1817
|
+
slug = slug.slice(1);
|
|
1187
1818
|
}
|
|
1188
|
-
|
|
1189
|
-
(acc, action) => {
|
|
1190
|
-
if (!acc[action.type]) {
|
|
1191
|
-
acc[action.type] = [];
|
|
1192
|
-
}
|
|
1193
|
-
acc[action.type].push(action);
|
|
1194
|
-
return acc;
|
|
1195
|
-
},
|
|
1196
|
-
{}
|
|
1197
|
-
);
|
|
1198
|
-
const appName = capitalize(appKey);
|
|
1199
|
-
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
1200
|
-
let output = `/* eslint-disable @typescript-eslint/naming-convention */
|
|
1201
|
-
/**
|
|
1202
|
-
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
1203
|
-
${versionComment}
|
|
1204
|
-
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1205
|
-
*
|
|
1206
|
-
* Usage:
|
|
1207
|
-
* import type { ${appName}Sdk } from './path/to/this/file'
|
|
1208
|
-
* const sdk = createZapierSdk() as unknown as ${appName}Sdk
|
|
1209
|
-
*
|
|
1210
|
-
* // Direct usage (per-call auth):
|
|
1211
|
-
* await sdk.apps.${appKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
|
|
1212
|
-
*
|
|
1213
|
-
* // Factory usage (pinned auth):
|
|
1214
|
-
* const my${appName} = sdk.apps.${appKey}({ authenticationId: 123 })
|
|
1215
|
-
* await my${appName}.search.user_by_email({ inputs: { email } })
|
|
1216
|
-
*/
|
|
1217
|
-
|
|
1218
|
-
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
1219
|
-
import { z } from 'zod'
|
|
1220
|
-
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
1221
|
-
|
|
1222
|
-
`;
|
|
1223
|
-
actions.forEach((action) => {
|
|
1224
|
-
if (action.inputFields.length > 0) {
|
|
1225
|
-
const inputTypeName = `${appName}${capitalize(action.type)}${capitalize(
|
|
1226
|
-
sanitizeActionName(action.key)
|
|
1227
|
-
)}Inputs`;
|
|
1228
|
-
output += `interface ${inputTypeName} {
|
|
1229
|
-
`;
|
|
1230
|
-
action.inputFields.forEach((field) => {
|
|
1231
|
-
const isOptional = !field.required;
|
|
1232
|
-
const fieldType = mapFieldTypeToTypeScript(field);
|
|
1233
|
-
const description = field.helpText ? ` /** ${escapeComment(field.helpText)} */
|
|
1234
|
-
` : "";
|
|
1235
|
-
output += `${description} ${sanitizeFieldName(field.key)}${isOptional ? "?" : ""}: ${fieldType}
|
|
1236
|
-
`;
|
|
1237
|
-
});
|
|
1238
|
-
output += `}
|
|
1239
|
-
|
|
1240
|
-
`;
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1243
|
-
Object.entries(actionsByType).forEach(([actionType, typeActions]) => {
|
|
1244
|
-
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
1245
|
-
output += `interface ${typeName} {
|
|
1246
|
-
`;
|
|
1247
|
-
typeActions.forEach((action) => {
|
|
1248
|
-
const actionName = sanitizeActionName(action.key);
|
|
1249
|
-
const description = action.description ? ` /** ${escapeComment(action.description)} */
|
|
1250
|
-
` : "";
|
|
1251
|
-
if (action.inputFields.length > 0) {
|
|
1252
|
-
const inputTypeName = `${appName}${capitalize(action.type)}${capitalize(
|
|
1253
|
-
sanitizeActionName(action.key)
|
|
1254
|
-
)}Inputs`;
|
|
1255
|
-
output += `${description} ${actionName}: (options: { inputs: ${inputTypeName} } & Omit<ActionExecutionOptions, 'inputs'>) => Promise<ActionExecutionResult>
|
|
1256
|
-
`;
|
|
1257
|
-
} else {
|
|
1258
|
-
output += `${description} ${actionName}: (options?: { inputs?: Record<string, any> } & ActionExecutionOptions) => Promise<ActionExecutionResult>
|
|
1259
|
-
`;
|
|
1260
|
-
}
|
|
1261
|
-
});
|
|
1262
|
-
output += `}
|
|
1263
|
-
|
|
1264
|
-
`;
|
|
1265
|
-
});
|
|
1266
|
-
output += `interface ${appName}AppProxy {
|
|
1267
|
-
`;
|
|
1268
|
-
Object.keys(actionsByType).forEach((actionType) => {
|
|
1269
|
-
const typeName = `${appName}${capitalize(actionType)}Actions`;
|
|
1270
|
-
output += ` ${actionType}: ${typeName}
|
|
1271
|
-
`;
|
|
1272
|
-
});
|
|
1273
|
-
output += generateFetchMethodSignature() + "\n";
|
|
1274
|
-
output += `}
|
|
1275
|
-
|
|
1276
|
-
`;
|
|
1277
|
-
output += `interface ${appName}AppFactory {
|
|
1278
|
-
`;
|
|
1279
|
-
output += ` (options: { authenticationId: number }): ${appName}AppProxy
|
|
1280
|
-
`;
|
|
1281
|
-
output += `}
|
|
1282
|
-
|
|
1283
|
-
`;
|
|
1284
|
-
output += `type ${appName}AppWithFactory = ${appName}AppFactory & ${appName}AppProxy
|
|
1285
|
-
|
|
1286
|
-
`;
|
|
1287
|
-
output += `export interface ${appName}Sdk {
|
|
1288
|
-
`;
|
|
1289
|
-
output += ` apps: {
|
|
1290
|
-
`;
|
|
1291
|
-
output += ` ${appKey}: ${appName}AppWithFactory
|
|
1292
|
-
`;
|
|
1293
|
-
output += ` }
|
|
1294
|
-
`;
|
|
1295
|
-
output += `}
|
|
1296
|
-
`;
|
|
1297
|
-
return output;
|
|
1298
|
-
}
|
|
1299
|
-
function generateEmptyTypesFile(appKey, version) {
|
|
1300
|
-
const appName = capitalize(appKey);
|
|
1301
|
-
const versionComment = version ? ` * Generated for ${appKey}@${version}` : ` * Generated for ${appKey}`;
|
|
1302
|
-
return `/* eslint-disable @typescript-eslint/naming-convention */
|
|
1303
|
-
/**
|
|
1304
|
-
* Auto-generated TypeScript types for Zapier ${appKey} actions
|
|
1305
|
-
${versionComment}
|
|
1306
|
-
* Generated on: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1307
|
-
*
|
|
1308
|
-
* No actions found for this app.
|
|
1309
|
-
*/
|
|
1310
|
-
|
|
1311
|
-
import type { ActionExecutionOptions, ActionExecutionResult } from '@zapier/zapier-sdk'
|
|
1312
|
-
import { z } from 'zod'
|
|
1313
|
-
import { RelayFetchSchema } from '@zapier/zapier-sdk'
|
|
1314
|
-
|
|
1315
|
-
interface ${appName}AppProxy {
|
|
1316
|
-
// No actions available
|
|
1317
|
-
${generateFetchMethodSignature()}
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
interface ${appName}AppFactory {
|
|
1321
|
-
(options: { authenticationId: number }): ${appName}AppProxy
|
|
1819
|
+
return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
|
|
1322
1820
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
export interface ${appName}Sdk {
|
|
1327
|
-
apps: {
|
|
1328
|
-
${appKey}: ${appName}AppWithFactory
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
`;
|
|
1332
|
-
}
|
|
1333
|
-
function capitalize(str) {
|
|
1334
|
-
return str.charAt(0).toUpperCase() + str.slice(1).replace(/[-_]/g, "");
|
|
1335
|
-
}
|
|
1336
|
-
function sanitizeActionName(actionKey) {
|
|
1337
|
-
let sanitized = actionKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1338
|
-
if (/^[0-9]/.test(sanitized)) {
|
|
1339
|
-
sanitized = "_" + sanitized;
|
|
1340
|
-
}
|
|
1341
|
-
return sanitized;
|
|
1342
|
-
}
|
|
1343
|
-
function sanitizeFieldName(fieldKey) {
|
|
1344
|
-
let sanitized = fieldKey.replace(/[^a-zA-Z0-9_$]/g, "_");
|
|
1345
|
-
if (/^[0-9]/.test(sanitized)) {
|
|
1346
|
-
sanitized = "_" + sanitized;
|
|
1821
|
+
function dashifySnakeCasedSlug(slug) {
|
|
1822
|
+
if (!isSnakeCasedSlug(slug)) {
|
|
1823
|
+
return slug;
|
|
1347
1824
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
function escapeComment(comment) {
|
|
1351
|
-
return comment.replace(/\*\//g, "*\\/").replace(/\r?\n/g, " ");
|
|
1352
|
-
}
|
|
1353
|
-
function mapFieldTypeToTypeScript(field) {
|
|
1354
|
-
if (field.choices && field.choices.length > 0) {
|
|
1355
|
-
const choiceValues = field.choices.filter(
|
|
1356
|
-
(choice) => choice.value !== void 0 && choice.value !== null && choice.value !== ""
|
|
1357
|
-
).map(
|
|
1358
|
-
(choice) => typeof choice.value === "string" ? `"${choice.value}"` : choice.value
|
|
1359
|
-
);
|
|
1360
|
-
if (choiceValues.length > 0) {
|
|
1361
|
-
return choiceValues.join(" | ");
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
switch (field.type?.toLowerCase()) {
|
|
1365
|
-
case "string":
|
|
1366
|
-
case "text":
|
|
1367
|
-
case "email":
|
|
1368
|
-
case "url":
|
|
1369
|
-
case "password":
|
|
1370
|
-
return "string";
|
|
1371
|
-
case "integer":
|
|
1372
|
-
case "number":
|
|
1373
|
-
return "number";
|
|
1374
|
-
case "boolean":
|
|
1375
|
-
return "boolean";
|
|
1376
|
-
case "datetime":
|
|
1377
|
-
case "date":
|
|
1378
|
-
return "string";
|
|
1379
|
-
// ISO date strings
|
|
1380
|
-
case "file":
|
|
1381
|
-
return "string";
|
|
1382
|
-
// File URL or content
|
|
1383
|
-
case "array":
|
|
1384
|
-
return "any[]";
|
|
1385
|
-
case "object":
|
|
1386
|
-
return "Record<string, any>";
|
|
1387
|
-
default:
|
|
1388
|
-
return "string | number | boolean";
|
|
1825
|
+
if (slug.startsWith("_")) {
|
|
1826
|
+
slug = slug.slice(1);
|
|
1389
1827
|
}
|
|
1828
|
+
return slug.replace(/_/g, "-");
|
|
1390
1829
|
}
|
|
1391
1830
|
|
|
1392
|
-
// src/
|
|
1393
|
-
|
|
1394
|
-
const {
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
entryPoints: [resolvedInput],
|
|
1409
|
-
bundle: true,
|
|
1410
|
-
platform: "node",
|
|
1411
|
-
target,
|
|
1412
|
-
format: cjs ? "cjs" : "esm",
|
|
1413
|
-
minify,
|
|
1414
|
-
write: false,
|
|
1415
|
-
external: [],
|
|
1416
|
-
// Bundle everything
|
|
1417
|
-
banner: {
|
|
1418
|
-
js: "#!/usr/bin/env node"
|
|
1419
|
-
}
|
|
1420
|
-
});
|
|
1421
|
-
if (result.errors.length > 0) {
|
|
1422
|
-
throw new Error(
|
|
1423
|
-
`Bundle failed: ${result.errors.map((e) => e.text).join(", ")}`
|
|
1831
|
+
// src/plugins/listApps/index.ts
|
|
1832
|
+
var listAppsPlugin = ({ context }) => {
|
|
1833
|
+
const listApps = createPaginatedFunction(async function listAppsPage(options) {
|
|
1834
|
+
const api = context.api;
|
|
1835
|
+
const opts = options;
|
|
1836
|
+
const appKeys = [...opts.appKeys ?? []].map(
|
|
1837
|
+
(key) => splitVersionedKey(key)[0]
|
|
1838
|
+
);
|
|
1839
|
+
if (opts.search) {
|
|
1840
|
+
const searchParams2 = {};
|
|
1841
|
+
searchParams2.term = opts.search;
|
|
1842
|
+
const searchEnvelope = await api.get(
|
|
1843
|
+
"/api/v4/implementations-meta/search/",
|
|
1844
|
+
{
|
|
1845
|
+
searchParams: searchParams2
|
|
1846
|
+
}
|
|
1424
1847
|
);
|
|
1848
|
+
const implementations = searchEnvelope.results.map(
|
|
1849
|
+
normalizeImplementationMetaToAppItem
|
|
1850
|
+
);
|
|
1851
|
+
const appKeysSet = new Set(appKeys);
|
|
1852
|
+
for (const implementation of implementations) {
|
|
1853
|
+
if (!appKeysSet.has(implementation.key)) {
|
|
1854
|
+
appKeysSet.add(implementation.key);
|
|
1855
|
+
appKeys.push(implementation.key);
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1425
1858
|
}
|
|
1426
|
-
const
|
|
1427
|
-
if (
|
|
1428
|
-
|
|
1429
|
-
}
|
|
1430
|
-
let finalOutput = bundledCode;
|
|
1431
|
-
if (returnString) {
|
|
1432
|
-
finalOutput = JSON.stringify(bundledCode);
|
|
1859
|
+
const searchParams = {};
|
|
1860
|
+
if (opts.pageSize) {
|
|
1861
|
+
searchParams.limit = opts.pageSize.toString();
|
|
1433
1862
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1863
|
+
searchParams.latest_only = "true";
|
|
1864
|
+
if (opts.cursor) {
|
|
1865
|
+
searchParams.offset = opts.cursor;
|
|
1437
1866
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
// src/functions/fetch/index.ts
|
|
1447
|
-
function transformUrlToRelayPath(url) {
|
|
1448
|
-
const targetUrl = new URL(url);
|
|
1449
|
-
const relayPath = `/relay/${targetUrl.hostname}${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
|
|
1450
|
-
return relayPath;
|
|
1451
|
-
}
|
|
1452
|
-
async function fetch(options) {
|
|
1453
|
-
const {
|
|
1454
|
-
url,
|
|
1455
|
-
method = "GET",
|
|
1456
|
-
body,
|
|
1457
|
-
headers,
|
|
1458
|
-
authenticationId,
|
|
1459
|
-
callbackUrl,
|
|
1460
|
-
authenticationTemplate,
|
|
1461
|
-
...config
|
|
1462
|
-
} = options;
|
|
1463
|
-
return relayFetch(
|
|
1464
|
-
url,
|
|
1465
|
-
{
|
|
1466
|
-
method,
|
|
1467
|
-
body,
|
|
1468
|
-
headers,
|
|
1469
|
-
authenticationId,
|
|
1470
|
-
callbackUrl,
|
|
1471
|
-
authenticationTemplate
|
|
1472
|
-
},
|
|
1473
|
-
config
|
|
1474
|
-
);
|
|
1475
|
-
}
|
|
1476
|
-
async function relayFetch(url, options = {}, config = {}) {
|
|
1477
|
-
const api = getOrCreateApiClient(config);
|
|
1478
|
-
const {
|
|
1479
|
-
authenticationId,
|
|
1480
|
-
callbackUrl,
|
|
1481
|
-
authenticationTemplate,
|
|
1482
|
-
method = "GET",
|
|
1483
|
-
body,
|
|
1484
|
-
...fetchOptions
|
|
1485
|
-
} = options;
|
|
1486
|
-
const relayPath = transformUrlToRelayPath(url);
|
|
1487
|
-
const headers = {};
|
|
1488
|
-
if (fetchOptions.headers) {
|
|
1489
|
-
const headerEntries = fetchOptions.headers instanceof Headers ? Array.from(fetchOptions.headers.entries()) : Object.entries(fetchOptions.headers);
|
|
1490
|
-
for (const [key, value] of headerEntries) {
|
|
1491
|
-
headers[key] = value;
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
if (authenticationId) {
|
|
1495
|
-
headers["X-Relay-Authentication-Id"] = authenticationId.toString();
|
|
1496
|
-
}
|
|
1497
|
-
if (callbackUrl) {
|
|
1498
|
-
headers["X-Relay-Callback-Url"] = callbackUrl;
|
|
1499
|
-
}
|
|
1500
|
-
if (authenticationTemplate) {
|
|
1501
|
-
headers["X-Authentication-Template"] = authenticationTemplate;
|
|
1502
|
-
}
|
|
1503
|
-
const requestOptions = {
|
|
1504
|
-
headers,
|
|
1505
|
-
authRequired: false,
|
|
1506
|
-
// Disable automatic Authorization header
|
|
1507
|
-
customErrorHandler: (response) => {
|
|
1508
|
-
if (!response.ok) {
|
|
1509
|
-
return new Error(
|
|
1510
|
-
`Relay request failed: ${response.status} ${response.statusText}`
|
|
1511
|
-
);
|
|
1867
|
+
if (appKeys.length > 0) {
|
|
1868
|
+
const groupedAppKeys = groupAppKeysByType(appKeys);
|
|
1869
|
+
if (groupedAppKeys.selectedApi.length > 0) {
|
|
1870
|
+
searchParams.selected_apis = groupedAppKeys.selectedApi.join(",");
|
|
1871
|
+
}
|
|
1872
|
+
if (groupedAppKeys.slug.length > 0) {
|
|
1873
|
+
searchParams.slugs = groupedAppKeys.slug.join(",");
|
|
1512
1874
|
}
|
|
1513
|
-
return void 0;
|
|
1514
1875
|
}
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
}
|
|
1520
|
-
if (!token) {
|
|
1521
|
-
const { getTokenFromEnvOrConfig: getTokenFromEnvOrConfig2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
1522
|
-
token = await getTokenFromEnvOrConfig2({
|
|
1523
|
-
onEvent: config.onEvent,
|
|
1524
|
-
fetch: config.fetch
|
|
1525
|
-
});
|
|
1526
|
-
}
|
|
1527
|
-
if (token) {
|
|
1528
|
-
const { getAuthorizationHeader: getAuthorizationHeader2 } = await Promise.resolve().then(() => (init_auth2(), auth_exports2));
|
|
1529
|
-
headers["X-Relay-Authorization"] = getAuthorizationHeader2(token);
|
|
1530
|
-
}
|
|
1531
|
-
return await api.fetch(relayPath, {
|
|
1532
|
-
method,
|
|
1533
|
-
body,
|
|
1534
|
-
headers: requestOptions.headers,
|
|
1535
|
-
authRequired: requestOptions.authRequired,
|
|
1536
|
-
customErrorHandler: requestOptions.customErrorHandler
|
|
1537
|
-
});
|
|
1538
|
-
}
|
|
1539
|
-
var RelayFetchSchema = z.object({
|
|
1540
|
-
url: z.string().url().describe("The URL to fetch (will be proxied through Relay)"),
|
|
1541
|
-
method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method"),
|
|
1542
|
-
body: z.string().optional().describe("Request body as a string"),
|
|
1543
|
-
authenticationId: z.number().int().optional().describe("Zapier authentication ID to use for the request"),
|
|
1544
|
-
callbackUrl: z.string().url().optional().describe("URL to send async response to (makes request async)"),
|
|
1545
|
-
authenticationTemplate: z.string().optional().describe(
|
|
1546
|
-
"Optional JSON string authentication template to bypass Notary lookup"
|
|
1547
|
-
),
|
|
1548
|
-
headers: z.record(z.string()).optional().describe("Request headers")
|
|
1549
|
-
}).describe("Make authenticated HTTP requests through Zapier's Relay service");
|
|
1550
|
-
var AppItemSchema = withFormatter(
|
|
1551
|
-
z.object({
|
|
1552
|
-
key: z.string(),
|
|
1553
|
-
name: z.string().optional(),
|
|
1554
|
-
description: z.string().optional(),
|
|
1555
|
-
category: z.string().optional()
|
|
1556
|
-
}),
|
|
1557
|
-
{
|
|
1558
|
-
format: (item) => {
|
|
1559
|
-
const details = [];
|
|
1560
|
-
if (item.description) {
|
|
1561
|
-
details.push({ text: item.description, style: "dim" });
|
|
1876
|
+
const implementationsEnvelope = await api.get(
|
|
1877
|
+
"/api/v4/implementations-meta/lookup/",
|
|
1878
|
+
{
|
|
1879
|
+
searchParams
|
|
1562
1880
|
}
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1881
|
+
);
|
|
1882
|
+
return {
|
|
1883
|
+
data: implementationsEnvelope.results.map(
|
|
1884
|
+
normalizeImplementationMetaToAppItem
|
|
1885
|
+
),
|
|
1886
|
+
nextCursor: extractCursor(implementationsEnvelope)
|
|
1887
|
+
};
|
|
1888
|
+
}, ListAppsSchema);
|
|
1889
|
+
return {
|
|
1890
|
+
listApps,
|
|
1891
|
+
context: {
|
|
1892
|
+
meta: {
|
|
1893
|
+
listApps: {
|
|
1894
|
+
inputSchema: ListAppsSchema
|
|
1895
|
+
}
|
|
1568
1896
|
}
|
|
1569
|
-
return {
|
|
1570
|
-
title: item.name || item.key,
|
|
1571
|
-
subtitle: `(${item.key})`,
|
|
1572
|
-
details
|
|
1573
|
-
};
|
|
1574
1897
|
}
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
// src/functions/listApps/schemas.ts
|
|
1579
|
-
var ListAppsSchema = withOutputSchema(
|
|
1898
|
+
};
|
|
1899
|
+
};
|
|
1900
|
+
var GetAppSchema = withOutputSchema(
|
|
1580
1901
|
z.object({
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
"Maximum number of items to return (1-200)"
|
|
1584
|
-
),
|
|
1585
|
-
offset: OffsetPropertySchema.optional().describe(
|
|
1586
|
-
"Number of items to skip for pagination"
|
|
1902
|
+
appKey: AppKeyPropertySchema.describe(
|
|
1903
|
+
"App key of app to fetch (e.g., 'SlackCLIAPI')"
|
|
1587
1904
|
)
|
|
1588
|
-
}).describe("
|
|
1905
|
+
}).describe("Get detailed information about a specific app"),
|
|
1589
1906
|
AppItemSchema
|
|
1590
1907
|
);
|
|
1591
1908
|
|
|
1592
|
-
// src/
|
|
1593
|
-
var
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1909
|
+
// src/plugins/getApp/index.ts
|
|
1910
|
+
var getAppPlugin = ({ sdk }) => {
|
|
1911
|
+
const getApp = createFunction(async function getApp2(options) {
|
|
1912
|
+
const { appKey } = options;
|
|
1913
|
+
const appsIterator = sdk.listApps({
|
|
1914
|
+
...options,
|
|
1915
|
+
appKeys: [appKey]
|
|
1916
|
+
}).items();
|
|
1917
|
+
const apps = [];
|
|
1918
|
+
for await (const app of appsIterator) {
|
|
1919
|
+
apps.push(app);
|
|
1920
|
+
break;
|
|
1921
|
+
}
|
|
1922
|
+
if (apps.length === 0) {
|
|
1923
|
+
throw new ZapierAppNotFoundError(appKey);
|
|
1924
|
+
}
|
|
1925
|
+
return {
|
|
1926
|
+
data: apps[0]
|
|
1927
|
+
};
|
|
1928
|
+
}, GetAppSchema);
|
|
1929
|
+
return {
|
|
1930
|
+
getApp,
|
|
1931
|
+
context: {
|
|
1932
|
+
meta: {
|
|
1933
|
+
getApp: {
|
|
1934
|
+
inputSchema: GetAppSchema
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
};
|
|
1609
1939
|
};
|
|
1610
1940
|
var ActionItemSchema = withFormatter(
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1941
|
+
ActionSchema.omit({ type: true, name: true }).extend({
|
|
1942
|
+
app_key: z.string(),
|
|
1943
|
+
// Mapped from selected_api
|
|
1944
|
+
action_type: ActionSchema.shape.type,
|
|
1945
|
+
// Mapped from original 'type' field
|
|
1946
|
+
title: z.string(),
|
|
1947
|
+
// Mapped from original 'name' field
|
|
1948
|
+
type: z.literal("action")
|
|
1949
|
+
// Fixed type identifier
|
|
1617
1950
|
}),
|
|
1618
1951
|
{
|
|
1619
1952
|
format: (item) => {
|
|
1620
1953
|
const details = [];
|
|
1621
|
-
details.push({
|
|
1622
|
-
|
|
1623
|
-
|
|
1954
|
+
details.push({
|
|
1955
|
+
text: `Type: ${item.action_type}`,
|
|
1956
|
+
style: "accent"
|
|
1957
|
+
});
|
|
1958
|
+
if (item.app_key) {
|
|
1959
|
+
details.push({
|
|
1960
|
+
text: `App: ${item.app_key}`,
|
|
1961
|
+
style: "normal"
|
|
1962
|
+
});
|
|
1624
1963
|
}
|
|
1625
1964
|
if (item.description) {
|
|
1626
1965
|
details.push({ text: item.description, style: "dim" });
|
|
1627
1966
|
}
|
|
1628
1967
|
return {
|
|
1629
|
-
title: item.name || item.key,
|
|
1968
|
+
title: item.title || item.name || item.key,
|
|
1630
1969
|
subtitle: `(${item.key})`,
|
|
1631
1970
|
details
|
|
1632
1971
|
};
|
|
@@ -1634,22 +1973,88 @@ var ActionItemSchema = withFormatter(
|
|
|
1634
1973
|
}
|
|
1635
1974
|
);
|
|
1636
1975
|
|
|
1637
|
-
// src/
|
|
1976
|
+
// src/plugins/listActions/schemas.ts
|
|
1638
1977
|
var ListActionsSchema = withOutputSchema(
|
|
1639
1978
|
z.object({
|
|
1640
|
-
appKey: AppKeyPropertySchema.
|
|
1641
|
-
|
|
1979
|
+
appKey: AppKeyPropertySchema.describe(
|
|
1980
|
+
"App key of actions to list (e.g., 'SlackCLIAPI')"
|
|
1981
|
+
),
|
|
1982
|
+
actionType: ActionTypePropertySchema.optional().describe(
|
|
1642
1983
|
"Filter actions by type"
|
|
1643
|
-
)
|
|
1984
|
+
),
|
|
1985
|
+
pageSize: z.number().min(1).optional().describe("Number of actions per page"),
|
|
1986
|
+
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
|
|
1644
1987
|
}).describe("List all actions for a specific app"),
|
|
1645
1988
|
ActionItemSchema
|
|
1646
1989
|
);
|
|
1647
1990
|
|
|
1648
|
-
// src/
|
|
1649
|
-
var
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1991
|
+
// src/plugins/listActions/index.ts
|
|
1992
|
+
var listActionsPlugin = ({ sdk, context }) => {
|
|
1993
|
+
const listActions = createPaginatedFunction(async function listActionsPage(options) {
|
|
1994
|
+
const { api } = context;
|
|
1995
|
+
const app = await sdk.getApp({ appKey: options.appKey });
|
|
1996
|
+
const implementationId = app.data.current_implementation_id?.split("@")[0];
|
|
1997
|
+
if (!implementationId) {
|
|
1998
|
+
throw new ZapierConfigurationError(
|
|
1999
|
+
"No current_implementation_id found for app",
|
|
2000
|
+
{ configType: "current_implementation_id" }
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
const searchParams = {
|
|
2004
|
+
global: "true",
|
|
2005
|
+
public_only: "true",
|
|
2006
|
+
selected_apis: implementationId
|
|
2007
|
+
};
|
|
2008
|
+
const data = await api.get("/api/v4/implementations/", {
|
|
2009
|
+
searchParams,
|
|
2010
|
+
customErrorHandler: ({ status }) => {
|
|
2011
|
+
if (status === 401) {
|
|
2012
|
+
return new ZapierAuthenticationError(
|
|
2013
|
+
`Authentication failed. Your token may not have permission to access implementations or may be expired. (HTTP ${status})`,
|
|
2014
|
+
{ statusCode: status }
|
|
2015
|
+
);
|
|
2016
|
+
}
|
|
2017
|
+
if (status === 403) {
|
|
2018
|
+
return new ZapierAuthenticationError(
|
|
2019
|
+
`Access forbidden. Your token may not have the required scopes to list implementations. (HTTP ${status})`,
|
|
2020
|
+
{ statusCode: status }
|
|
2021
|
+
);
|
|
2022
|
+
}
|
|
2023
|
+
return void 0;
|
|
2024
|
+
}
|
|
2025
|
+
});
|
|
2026
|
+
let allActions = [];
|
|
2027
|
+
for (const implementation of data.results || []) {
|
|
2028
|
+
if (implementation.actions) {
|
|
2029
|
+
for (const action of implementation.actions) {
|
|
2030
|
+
const actionWithContext = {
|
|
2031
|
+
...action,
|
|
2032
|
+
selected_api: action.selected_api || implementation.selected_api
|
|
2033
|
+
};
|
|
2034
|
+
allActions.push(normalizeActionItem(actionWithContext));
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
if (options.actionType) {
|
|
2039
|
+
allActions = allActions.filter(
|
|
2040
|
+
(action) => action.action_type === options.actionType
|
|
2041
|
+
);
|
|
2042
|
+
}
|
|
2043
|
+
return {
|
|
2044
|
+
data: allActions,
|
|
2045
|
+
nextCursor: void 0
|
|
2046
|
+
};
|
|
2047
|
+
}, ListActionsSchema);
|
|
2048
|
+
return {
|
|
2049
|
+
listActions,
|
|
2050
|
+
context: {
|
|
2051
|
+
meta: {
|
|
2052
|
+
listActions: {
|
|
2053
|
+
inputSchema: ListActionsSchema
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
1653
2058
|
};
|
|
1654
2059
|
var GetActionSchema = z.object({
|
|
1655
2060
|
appKey: AppKeyPropertySchema,
|
|
@@ -1657,299 +2062,584 @@ var GetActionSchema = z.object({
|
|
|
1657
2062
|
actionKey: ActionKeyPropertySchema
|
|
1658
2063
|
}).describe("Get detailed information about a specific action");
|
|
1659
2064
|
|
|
1660
|
-
// src/
|
|
1661
|
-
var
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
2065
|
+
// src/plugins/getAction/index.ts
|
|
2066
|
+
var getActionPlugin = ({ sdk }) => {
|
|
2067
|
+
const getAction = createFunction(async function getAction2(options) {
|
|
2068
|
+
const { actionKey, actionType, appKey } = options;
|
|
2069
|
+
const actionsResult = await sdk.listActions({ appKey });
|
|
2070
|
+
for (const action of actionsResult.data) {
|
|
2071
|
+
if (action.key === actionKey && action.action_type === actionType) {
|
|
2072
|
+
return { data: action };
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
throw new ZapierResourceNotFoundError(
|
|
2076
|
+
`Action not found: ${actionKey} with type ${actionType}`,
|
|
2077
|
+
{ resourceType: "Action", resourceId: `${actionKey} (${actionType})` }
|
|
2078
|
+
);
|
|
2079
|
+
}, GetActionSchema);
|
|
2080
|
+
return {
|
|
2081
|
+
getAction,
|
|
2082
|
+
context: {
|
|
2083
|
+
meta: {
|
|
2084
|
+
getAction: {
|
|
2085
|
+
inputSchema: GetActionSchema
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
1665
2090
|
};
|
|
1666
2091
|
var RunActionSchema = z.object({
|
|
1667
2092
|
appKey: AppKeyPropertySchema,
|
|
1668
2093
|
actionType: ActionTypePropertySchema,
|
|
1669
2094
|
actionKey: ActionKeyPropertySchema,
|
|
2095
|
+
authenticationId: AuthenticationIdPropertySchema.nullable().optional(),
|
|
1670
2096
|
inputs: InputsPropertySchema.optional().describe(
|
|
1671
2097
|
"Input parameters for the action"
|
|
1672
2098
|
),
|
|
1673
|
-
|
|
2099
|
+
pageSize: z.number().min(1).optional().describe("Number of results per page"),
|
|
2100
|
+
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
|
|
1674
2101
|
}).describe("Execute an action with the given inputs");
|
|
1675
2102
|
|
|
1676
|
-
// src/
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
2103
|
+
// src/plugins/runAction/index.ts
|
|
2104
|
+
async function executeAction(actionOptions) {
|
|
2105
|
+
const {
|
|
2106
|
+
api,
|
|
2107
|
+
sdk,
|
|
2108
|
+
appKey,
|
|
2109
|
+
actionKey,
|
|
2110
|
+
actionType,
|
|
2111
|
+
executionOptions,
|
|
2112
|
+
authenticationId
|
|
2113
|
+
} = actionOptions;
|
|
2114
|
+
const appData = await sdk.getApp({ appKey });
|
|
2115
|
+
const selectedApi = appData.data.current_implementation_id;
|
|
2116
|
+
if (!selectedApi) {
|
|
2117
|
+
throw new ZapierConfigurationError(
|
|
2118
|
+
"No current_implementation_id found for app",
|
|
2119
|
+
{ configType: "current_implementation_id" }
|
|
2120
|
+
);
|
|
2121
|
+
}
|
|
2122
|
+
const runRequestData = {
|
|
2123
|
+
selected_api: selectedApi,
|
|
2124
|
+
action_key: actionKey,
|
|
2125
|
+
action_type: actionType,
|
|
2126
|
+
inputs: executionOptions.inputs || {}
|
|
2127
|
+
};
|
|
2128
|
+
if (authenticationId !== null && authenticationId !== void 0) {
|
|
2129
|
+
runRequestData.authentication_id = authenticationId;
|
|
2130
|
+
}
|
|
2131
|
+
const runRequest = {
|
|
2132
|
+
data: runRequestData
|
|
2133
|
+
};
|
|
2134
|
+
const runData = await api.post("/api/actions/v1/runs", runRequest);
|
|
2135
|
+
const runId = runData.data.id;
|
|
2136
|
+
return await api.poll(`/api/actions/v1/runs/${runId}`, {
|
|
2137
|
+
successStatus: 200,
|
|
2138
|
+
pendingStatus: 202,
|
|
2139
|
+
resultExtractor: (result) => result.data
|
|
2140
|
+
});
|
|
2141
|
+
}
|
|
2142
|
+
var runActionPlugin = ({ sdk, context }) => {
|
|
2143
|
+
const runAction = createPaginatedFunction(async function runActionPage(options) {
|
|
2144
|
+
const { api } = context;
|
|
2145
|
+
const {
|
|
2146
|
+
appKey,
|
|
2147
|
+
actionKey,
|
|
2148
|
+
actionType,
|
|
2149
|
+
authenticationId,
|
|
2150
|
+
inputs = {}
|
|
2151
|
+
} = options;
|
|
2152
|
+
const actionData = await sdk.getAction({
|
|
2153
|
+
appKey,
|
|
2154
|
+
actionKey,
|
|
2155
|
+
actionType
|
|
2156
|
+
});
|
|
2157
|
+
if (actionData.data.action_type !== actionType) {
|
|
2158
|
+
throw new ZapierValidationError(
|
|
2159
|
+
`Action type mismatch: expected ${actionType}, got ${actionData.data.action_type}`
|
|
2160
|
+
);
|
|
2161
|
+
}
|
|
2162
|
+
const result = await executeAction({
|
|
2163
|
+
api,
|
|
2164
|
+
sdk,
|
|
2165
|
+
appKey,
|
|
2166
|
+
actionKey,
|
|
2167
|
+
actionType,
|
|
2168
|
+
executionOptions: { inputs },
|
|
2169
|
+
authenticationId});
|
|
2170
|
+
if (result.errors && result.errors.length > 0) {
|
|
2171
|
+
const errorMessage = result.errors.map(
|
|
2172
|
+
(error) => error.detail || error.title || "Unknown error"
|
|
2173
|
+
).join("; ");
|
|
2174
|
+
throw new ZapierActionError(`Action execution failed: ${errorMessage}`, {
|
|
2175
|
+
appKey,
|
|
2176
|
+
actionKey
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
return {
|
|
2180
|
+
data: result.results || [],
|
|
2181
|
+
nextCursor: void 0
|
|
2182
|
+
// No pagination implemented yet
|
|
2183
|
+
};
|
|
2184
|
+
}, RunActionSchema);
|
|
2185
|
+
return {
|
|
2186
|
+
runAction,
|
|
2187
|
+
context: {
|
|
2188
|
+
meta: {
|
|
2189
|
+
runAction: {
|
|
2190
|
+
inputSchema: RunActionSchema
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
};
|
|
1681
2195
|
};
|
|
1682
|
-
var
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
2196
|
+
var ListAuthenticationsSchema = z.object({
|
|
2197
|
+
appKey: AppKeyPropertySchema.optional().describe(
|
|
2198
|
+
"App key of authentications to list (e.g., 'SlackCLIAPI')"
|
|
2199
|
+
),
|
|
2200
|
+
search: z.string().optional().describe("Search term to filter authentications by title"),
|
|
2201
|
+
title: z.string().optional().describe("Filter authentications by exact title match"),
|
|
2202
|
+
account_id: z.string().optional().describe("Filter by account ID"),
|
|
2203
|
+
owner: z.string().optional().describe("Filter by owner"),
|
|
2204
|
+
pageSize: z.number().min(1).optional().describe("Number of authentications per page"),
|
|
2205
|
+
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
|
|
2206
|
+
}).describe("List available authentications with optional filtering");
|
|
2207
|
+
|
|
2208
|
+
// src/plugins/listAuthentications/index.ts
|
|
2209
|
+
var listAuthenticationsPlugin = ({ sdk, context }) => {
|
|
2210
|
+
const listAuthentications = createPaginatedFunction(
|
|
2211
|
+
async function listAuthenticationsPage(options) {
|
|
2212
|
+
const { api } = context;
|
|
2213
|
+
const searchParams = {};
|
|
2214
|
+
if (options.appKey) {
|
|
2215
|
+
const app = await sdk.getApp({
|
|
2216
|
+
appKey: options.appKey
|
|
1699
2217
|
});
|
|
2218
|
+
const selectedApi = app.data.current_implementation_id;
|
|
2219
|
+
if (selectedApi) {
|
|
2220
|
+
const versionlessApi = selectedApi.split("@")[0];
|
|
2221
|
+
searchParams.versionless_selected_api = versionlessApi;
|
|
2222
|
+
}
|
|
1700
2223
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
2224
|
+
if (options.search) {
|
|
2225
|
+
searchParams.search = options.search;
|
|
2226
|
+
} else if (options.title) {
|
|
2227
|
+
searchParams.search = options.title;
|
|
2228
|
+
}
|
|
2229
|
+
if (options.account_id) {
|
|
2230
|
+
searchParams.account_id = options.account_id;
|
|
2231
|
+
}
|
|
2232
|
+
if (options.owner) {
|
|
2233
|
+
searchParams.owner = options.owner;
|
|
2234
|
+
}
|
|
2235
|
+
searchParams.limit = options.pageSize.toString();
|
|
2236
|
+
if (options.cursor) {
|
|
2237
|
+
searchParams.offset = options.cursor;
|
|
2238
|
+
}
|
|
2239
|
+
const data = await api.get(
|
|
2240
|
+
"/api/v4/authentications/",
|
|
2241
|
+
{
|
|
2242
|
+
searchParams,
|
|
2243
|
+
customErrorHandler: ({ status }) => {
|
|
2244
|
+
if (status === 401) {
|
|
2245
|
+
return new ZapierAuthenticationError(
|
|
2246
|
+
`Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${status})`,
|
|
2247
|
+
{ statusCode: status }
|
|
2248
|
+
);
|
|
2249
|
+
}
|
|
2250
|
+
if (status === 403) {
|
|
2251
|
+
return new ZapierAuthenticationError(
|
|
2252
|
+
`Access forbidden. Your token may not have the required scopes to list authentications. (HTTP ${status})`,
|
|
2253
|
+
{ statusCode: status }
|
|
2254
|
+
);
|
|
2255
|
+
}
|
|
2256
|
+
return void 0;
|
|
2257
|
+
},
|
|
2258
|
+
authRequired: true
|
|
2259
|
+
}
|
|
2260
|
+
);
|
|
2261
|
+
let auths = (data.results || []).map(
|
|
2262
|
+
(auth) => normalizeAuthenticationItem(auth)
|
|
2263
|
+
);
|
|
2264
|
+
if (options.title) {
|
|
2265
|
+
auths = auths.filter((auth) => auth.title === options.title);
|
|
1710
2266
|
}
|
|
1711
2267
|
return {
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
details
|
|
2268
|
+
data: auths,
|
|
2269
|
+
nextCursor: extractCursor(data)
|
|
1715
2270
|
};
|
|
2271
|
+
},
|
|
2272
|
+
ListAuthenticationsSchema
|
|
2273
|
+
);
|
|
2274
|
+
return {
|
|
2275
|
+
listAuthentications,
|
|
2276
|
+
context: {
|
|
2277
|
+
meta: {
|
|
2278
|
+
listAuthentications: {
|
|
2279
|
+
inputSchema: ListAuthenticationsSchema
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
1716
2282
|
}
|
|
1717
|
-
}
|
|
1718
|
-
);
|
|
1719
|
-
|
|
1720
|
-
// src/functions/listAuthentications/schemas.ts
|
|
1721
|
-
var ListAuthenticationsSchema = withOutputSchema(
|
|
1722
|
-
z.object({
|
|
1723
|
-
appKey: AppKeyPropertySchema.optional().describe(
|
|
1724
|
-
"App slug to get authentications for (e.g., 'slack', 'github')"
|
|
1725
|
-
),
|
|
1726
|
-
search: z.string().optional().describe("Search term to filter authentications by title"),
|
|
1727
|
-
title: z.string().optional().describe("Filter authentications by exact title match"),
|
|
1728
|
-
account_id: z.string().optional().describe("Filter by account ID"),
|
|
1729
|
-
owner: z.string().optional().describe("Filter by owner"),
|
|
1730
|
-
limit: LimitPropertySchema.optional().describe(
|
|
1731
|
-
"Maximum number of items to return (1-200)"
|
|
1732
|
-
),
|
|
1733
|
-
offset: OffsetPropertySchema.optional().describe(
|
|
1734
|
-
"Number of items to skip for pagination"
|
|
1735
|
-
)
|
|
1736
|
-
}).describe("List available authentications with optional filtering"),
|
|
1737
|
-
AuthItemSchema
|
|
1738
|
-
);
|
|
1739
|
-
|
|
1740
|
-
// src/functions/listAuthentications/info.ts
|
|
1741
|
-
var listAuthenticationsInfo = {
|
|
1742
|
-
name: listAuthentications.name,
|
|
1743
|
-
inputSchema: ListAuthenticationsSchema,
|
|
1744
|
-
implementation: listAuthentications
|
|
1745
|
-
};
|
|
1746
|
-
var GetAuthenticationSchema = withOutputSchema(
|
|
1747
|
-
z.object({
|
|
1748
|
-
authenticationId: z.number().int().positive().describe("Authentication ID to retrieve")
|
|
1749
|
-
}).describe("Get a specific authentication by ID"),
|
|
1750
|
-
AuthItemSchema
|
|
1751
|
-
);
|
|
1752
|
-
|
|
1753
|
-
// src/functions/getAuthentication/info.ts
|
|
1754
|
-
var getAuthenticationInfo = {
|
|
1755
|
-
name: getAuthentication.name,
|
|
1756
|
-
inputSchema: GetAuthenticationSchema,
|
|
1757
|
-
implementation: getAuthentication
|
|
2283
|
+
};
|
|
1758
2284
|
};
|
|
1759
|
-
var
|
|
1760
|
-
z.
|
|
1761
|
-
|
|
1762
|
-
"App slug to get authentications for (e.g., 'slack', 'github')"
|
|
1763
|
-
),
|
|
1764
|
-
search: z.string().optional().describe("Search term to filter authentications by title"),
|
|
1765
|
-
title: z.string().optional().describe("Filter authentications by exact title match"),
|
|
1766
|
-
account_id: z.string().optional().describe("Filter by account ID"),
|
|
1767
|
-
owner: z.string().optional().describe("Filter by owner"),
|
|
1768
|
-
limit: LimitPropertySchema.optional().describe(
|
|
1769
|
-
"Maximum number of items to return (1-200)"
|
|
1770
|
-
),
|
|
1771
|
-
offset: OffsetPropertySchema.optional().describe(
|
|
1772
|
-
"Number of items to skip for pagination"
|
|
1773
|
-
)
|
|
1774
|
-
}).describe("Find the first authentication matching the criteria"),
|
|
1775
|
-
AuthItemSchema
|
|
1776
|
-
);
|
|
2285
|
+
var GetAuthenticationSchema = z.object({
|
|
2286
|
+
authenticationId: z.number().int().positive().describe("Authentication ID to retrieve")
|
|
2287
|
+
}).describe("Get a specific authentication by ID");
|
|
1777
2288
|
|
|
1778
|
-
// src/
|
|
1779
|
-
var
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
2289
|
+
// src/plugins/getAuthentication/index.ts
|
|
2290
|
+
var getAuthenticationPlugin = ({ context }) => {
|
|
2291
|
+
const getAuthentication = createFunction(async function getAuthentication2(options) {
|
|
2292
|
+
const { api } = context;
|
|
2293
|
+
const { authenticationId } = options;
|
|
2294
|
+
const data = await api.get(
|
|
2295
|
+
`/api/v4/authentications/${authenticationId}/`,
|
|
2296
|
+
{
|
|
2297
|
+
customErrorHandler: ({ status }) => {
|
|
2298
|
+
if (status === 401) {
|
|
2299
|
+
return new ZapierAuthenticationError(
|
|
2300
|
+
`Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${status})`,
|
|
2301
|
+
{ statusCode: status }
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
if (status === 403) {
|
|
2305
|
+
return new ZapierAuthenticationError(
|
|
2306
|
+
`Access forbidden. Your token may not have the required scopes to get authentication ${authenticationId}. (HTTP ${status})`,
|
|
2307
|
+
{ statusCode: status }
|
|
2308
|
+
);
|
|
2309
|
+
}
|
|
2310
|
+
if (status === 404) {
|
|
2311
|
+
return new ZapierResourceNotFoundError(
|
|
2312
|
+
`Authentication ${authenticationId} not found. It may not exist or you may not have access to it. (HTTP ${status})`,
|
|
2313
|
+
{
|
|
2314
|
+
resourceType: "Authentication",
|
|
2315
|
+
resourceId: String(authenticationId)
|
|
2316
|
+
}
|
|
2317
|
+
);
|
|
2318
|
+
}
|
|
2319
|
+
return void 0;
|
|
2320
|
+
},
|
|
2321
|
+
authRequired: true
|
|
2322
|
+
}
|
|
2323
|
+
);
|
|
2324
|
+
return {
|
|
2325
|
+
data: normalizeAuthenticationItem(data)
|
|
2326
|
+
};
|
|
2327
|
+
}, GetAuthenticationSchema);
|
|
2328
|
+
return {
|
|
2329
|
+
getAuthentication,
|
|
2330
|
+
context: {
|
|
2331
|
+
meta: {
|
|
2332
|
+
getAuthentication: {
|
|
2333
|
+
inputSchema: GetAuthenticationSchema
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
};
|
|
1783
2338
|
};
|
|
1784
|
-
var
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
limit: LimitPropertySchema.optional().describe(
|
|
1794
|
-
"Maximum number of items to return (1-200)"
|
|
1795
|
-
),
|
|
1796
|
-
offset: OffsetPropertySchema.optional().describe(
|
|
1797
|
-
"Number of items to skip for pagination"
|
|
1798
|
-
)
|
|
1799
|
-
}).describe("Find a unique authentication matching the criteria"),
|
|
1800
|
-
AuthItemSchema
|
|
1801
|
-
);
|
|
2339
|
+
var FindFirstAuthenticationSchema = z.object({
|
|
2340
|
+
appKey: AppKeyPropertySchema.optional().describe(
|
|
2341
|
+
"App key of authentication to find (e.g., 'SlackCLIAPI')"
|
|
2342
|
+
),
|
|
2343
|
+
search: z.string().optional().describe("Search term to filter authentications by title"),
|
|
2344
|
+
title: z.string().optional().describe("Filter authentications by exact title match"),
|
|
2345
|
+
account_id: z.string().optional().describe("Filter by account ID"),
|
|
2346
|
+
owner: z.string().optional().describe("Filter by owner")
|
|
2347
|
+
}).describe("Find the first authentication matching the criteria");
|
|
1802
2348
|
|
|
1803
|
-
// src/
|
|
1804
|
-
var
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
key: z.string(),
|
|
1812
|
-
name: z.string().optional(),
|
|
1813
|
-
description: z.string().optional()
|
|
1814
|
-
}),
|
|
1815
|
-
{
|
|
1816
|
-
format: (item) => {
|
|
1817
|
-
const details = [];
|
|
1818
|
-
if (item.description) {
|
|
1819
|
-
details.push({ text: item.description, style: "dim" });
|
|
1820
|
-
}
|
|
2349
|
+
// src/plugins/findFirstAuthentication/index.ts
|
|
2350
|
+
var findFirstAuthenticationPlugin = ({ sdk }) => {
|
|
2351
|
+
const findFirstAuthentication = createFunction(
|
|
2352
|
+
async function findFirstAuthentication2(options = {}) {
|
|
2353
|
+
const authsResponse = await sdk.listAuthentications({
|
|
2354
|
+
...options,
|
|
2355
|
+
maxItems: 1
|
|
2356
|
+
});
|
|
1821
2357
|
return {
|
|
1822
|
-
|
|
1823
|
-
subtitle: `(${item.key})`,
|
|
1824
|
-
details
|
|
2358
|
+
data: authsResponse.data.length > 0 ? authsResponse.data[0] : null
|
|
1825
2359
|
};
|
|
2360
|
+
},
|
|
2361
|
+
FindFirstAuthenticationSchema
|
|
2362
|
+
);
|
|
2363
|
+
return {
|
|
2364
|
+
findFirstAuthentication,
|
|
2365
|
+
context: {
|
|
2366
|
+
meta: {
|
|
2367
|
+
findFirstAuthentication: {
|
|
2368
|
+
inputSchema: FindFirstAuthenticationSchema
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
1826
2371
|
}
|
|
1827
|
-
}
|
|
1828
|
-
);
|
|
1829
|
-
|
|
1830
|
-
// src/functions/listFields/schemas.ts
|
|
1831
|
-
var ListFieldsSchema = withOutputSchema(
|
|
1832
|
-
z.object({
|
|
1833
|
-
appKey: AppKeyPropertySchema,
|
|
1834
|
-
actionType: ActionTypePropertySchema,
|
|
1835
|
-
actionKey: ActionKeyPropertySchema,
|
|
1836
|
-
authenticationId: AuthenticationIdPropertySchema.optional(),
|
|
1837
|
-
params: ParamsPropertySchema.optional().describe(
|
|
1838
|
-
"Additional parameters that may affect available fields"
|
|
1839
|
-
)
|
|
1840
|
-
}).describe("Get the input fields required for a specific action"),
|
|
1841
|
-
FieldItemSchema
|
|
1842
|
-
);
|
|
1843
|
-
|
|
1844
|
-
// src/functions/listFields/info.ts
|
|
1845
|
-
var listFieldsInfo = {
|
|
1846
|
-
name: listFields.name,
|
|
1847
|
-
inputSchema: ListFieldsSchema,
|
|
1848
|
-
implementation: listFields
|
|
2372
|
+
};
|
|
1849
2373
|
};
|
|
1850
|
-
var
|
|
1851
|
-
appKey: AppKeyPropertySchema.describe(
|
|
1852
|
-
|
|
1853
|
-
output: OutputPropertySchema.optional().describe(
|
|
1854
|
-
"Output file path (defaults to generated/<appKey>.ts)"
|
|
2374
|
+
var FindUniqueAuthenticationSchema = z.object({
|
|
2375
|
+
appKey: AppKeyPropertySchema.optional().describe(
|
|
2376
|
+
"App key of authentication to find (e.g., 'SlackCLIAPI')"
|
|
1855
2377
|
),
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
)
|
|
1859
|
-
|
|
2378
|
+
search: z.string().optional().describe("Search term to filter authentications by title"),
|
|
2379
|
+
title: z.string().optional().describe("Filter authentications by exact title match"),
|
|
2380
|
+
account_id: z.string().optional().describe("Filter by account ID"),
|
|
2381
|
+
owner: z.string().optional().describe("Filter by owner")
|
|
2382
|
+
}).describe("Find a unique authentication matching the criteria");
|
|
1860
2383
|
|
|
1861
|
-
// src/
|
|
1862
|
-
var
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
2384
|
+
// src/plugins/findUniqueAuthentication/index.ts
|
|
2385
|
+
var findUniqueAuthenticationPlugin = ({ sdk }) => {
|
|
2386
|
+
const findUniqueAuthentication = createFunction(
|
|
2387
|
+
async function findUniqueAuthentication2(options = {}) {
|
|
2388
|
+
const authsResponse = await sdk.listAuthentications({
|
|
2389
|
+
...options,
|
|
2390
|
+
maxItems: 2
|
|
2391
|
+
// Get up to 2 to check for uniqueness
|
|
2392
|
+
});
|
|
2393
|
+
if (authsResponse.data.length === 0) {
|
|
2394
|
+
throw new ZapierResourceNotFoundError(
|
|
2395
|
+
"No authentication found matching the specified criteria",
|
|
2396
|
+
{ resourceType: "Authentication" }
|
|
2397
|
+
);
|
|
2398
|
+
}
|
|
2399
|
+
if (authsResponse.data.length > 1) {
|
|
2400
|
+
throw new ZapierValidationError(
|
|
2401
|
+
"Multiple authentications found matching the specified criteria. Expected exactly one."
|
|
2402
|
+
);
|
|
2403
|
+
}
|
|
2404
|
+
return {
|
|
2405
|
+
data: authsResponse.data[0]
|
|
2406
|
+
};
|
|
2407
|
+
},
|
|
2408
|
+
FindUniqueAuthenticationSchema
|
|
2409
|
+
);
|
|
2410
|
+
return {
|
|
2411
|
+
findUniqueAuthentication,
|
|
2412
|
+
context: {
|
|
2413
|
+
meta: {
|
|
2414
|
+
findUniqueAuthentication: {
|
|
2415
|
+
inputSchema: FindUniqueAuthenticationSchema
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
1866
2420
|
};
|
|
1867
|
-
var
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
2421
|
+
var ListInputFieldsSchema = z.object({
|
|
2422
|
+
appKey: AppKeyPropertySchema,
|
|
2423
|
+
actionType: ActionTypePropertySchema,
|
|
2424
|
+
actionKey: ActionKeyPropertySchema,
|
|
2425
|
+
authenticationId: AuthenticationIdPropertySchema.nullable().optional(),
|
|
2426
|
+
inputs: InputsPropertySchema.optional().describe(
|
|
2427
|
+
"Current input values that may affect available fields"
|
|
1871
2428
|
),
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
cjs: z.boolean().default(false).describe("Output CommonJS format instead of ESM")
|
|
1876
|
-
}).describe("Bundle TypeScript code into executable JavaScript");
|
|
2429
|
+
pageSize: z.number().min(1).optional().describe("Number of input fields per page"),
|
|
2430
|
+
maxItems: z.number().min(1).optional().describe("Maximum total items to return across all pages")
|
|
2431
|
+
}).describe("Get the input fields required for a specific action");
|
|
1877
2432
|
|
|
1878
|
-
// src/
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
2433
|
+
// src/plugins/listInputFields/index.ts
|
|
2434
|
+
function getInputFieldTypeFromNeed(need) {
|
|
2435
|
+
if (need.list) {
|
|
2436
|
+
return "ARRAY" /* ARRAY */;
|
|
2437
|
+
}
|
|
2438
|
+
const typeMap = {
|
|
2439
|
+
string: "STRING" /* STRING */,
|
|
2440
|
+
decimal: "NUMBER" /* NUMBER */,
|
|
2441
|
+
integer: "INTEGER" /* INTEGER */,
|
|
2442
|
+
boolean: "BOOLEAN" /* BOOLEAN */,
|
|
2443
|
+
dict: "OBJECT" /* OBJECT */
|
|
2444
|
+
};
|
|
2445
|
+
return typeMap[need.type || ""] || "STRING" /* STRING */;
|
|
2446
|
+
}
|
|
2447
|
+
function getInputFieldFormatFromNeed(need) {
|
|
2448
|
+
if (need.prefill || need.choices) {
|
|
2449
|
+
return "SELECT" /* SELECT */;
|
|
2450
|
+
}
|
|
2451
|
+
const formatMap = {
|
|
2452
|
+
text: "MULTILINE" /* MULTILINE */,
|
|
2453
|
+
datetime: "DATETIME" /* DATETIME */,
|
|
2454
|
+
file: "FILE" /* FILE */,
|
|
2455
|
+
password: "PASSWORD" /* PASSWORD */,
|
|
2456
|
+
code: "CODE" /* CODE */
|
|
2457
|
+
};
|
|
2458
|
+
return formatMap[need.type || ""];
|
|
2459
|
+
}
|
|
2460
|
+
function getItemsTypeFromNeed(need) {
|
|
2461
|
+
if (!need.list) {
|
|
2462
|
+
return void 0;
|
|
2463
|
+
}
|
|
2464
|
+
const typeMap = {
|
|
2465
|
+
string: "STRING" /* STRING */,
|
|
2466
|
+
decimal: "NUMBER" /* NUMBER */,
|
|
2467
|
+
integer: "INTEGER" /* INTEGER */,
|
|
2468
|
+
boolean: "BOOLEAN" /* BOOLEAN */,
|
|
2469
|
+
dict: "OBJECT" /* OBJECT */
|
|
2470
|
+
};
|
|
2471
|
+
return typeMap[need.type || ""] || "STRING" /* STRING */;
|
|
2472
|
+
}
|
|
2473
|
+
function transformNeedToInputFieldItem(need) {
|
|
2474
|
+
const itemsType = getItemsTypeFromNeed(need);
|
|
2475
|
+
return {
|
|
2476
|
+
...need,
|
|
2477
|
+
// Pass through all original Need fields
|
|
2478
|
+
id: need.key,
|
|
2479
|
+
default_value: need.default || "",
|
|
2480
|
+
depends_on: need.depends_on || [],
|
|
2481
|
+
description: need.help_text || "",
|
|
2482
|
+
invalidates_input_fields: need.alters_custom_fields || false,
|
|
2483
|
+
is_required: need.required || false,
|
|
2484
|
+
placeholder: need.placeholder || "",
|
|
2485
|
+
title: need.label || "",
|
|
2486
|
+
value_type: getInputFieldTypeFromNeed(need),
|
|
2487
|
+
format: getInputFieldFormatFromNeed(need),
|
|
2488
|
+
items: itemsType ? { type: itemsType } : void 0
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
var listInputFieldsPlugin = ({ sdk, context }) => {
|
|
2492
|
+
const listInputFields = createPaginatedFunction(
|
|
2493
|
+
async function listInputFieldsPage(options) {
|
|
2494
|
+
const { api } = context;
|
|
2495
|
+
const { appKey, actionKey, actionType, authenticationId, inputs } = options;
|
|
2496
|
+
const appData = await sdk.getApp({ appKey });
|
|
2497
|
+
const selectedApi = appData.data.current_implementation_id;
|
|
2498
|
+
if (!selectedApi) {
|
|
2499
|
+
throw new ZapierConfigurationError(
|
|
2500
|
+
"No current_implementation_id found for app",
|
|
2501
|
+
{ configType: "current_implementation_id" }
|
|
2502
|
+
);
|
|
2503
|
+
}
|
|
2504
|
+
const needsRequest = {
|
|
2505
|
+
selected_api: selectedApi,
|
|
2506
|
+
action: actionKey,
|
|
2507
|
+
type_of: actionType,
|
|
2508
|
+
params: inputs || {}
|
|
2509
|
+
};
|
|
2510
|
+
if (authenticationId !== null) {
|
|
2511
|
+
needsRequest.authentication_id = authenticationId;
|
|
2512
|
+
}
|
|
2513
|
+
const needsData = await api.post(
|
|
2514
|
+
"/api/v4/implementations/needs/",
|
|
2515
|
+
needsRequest
|
|
2516
|
+
);
|
|
2517
|
+
if (!needsData.success) {
|
|
2518
|
+
throw new ZapierApiError(
|
|
2519
|
+
`Failed to get action fields: ${needsData.errors?.join(", ") || "Unknown error"}`
|
|
2520
|
+
);
|
|
2521
|
+
}
|
|
2522
|
+
const inputFields = (needsData.needs || []).map(
|
|
2523
|
+
transformNeedToInputFieldItem
|
|
2524
|
+
);
|
|
2525
|
+
return {
|
|
2526
|
+
data: inputFields,
|
|
2527
|
+
nextCursor: void 0
|
|
2528
|
+
// No pagination needed since we return all input fields
|
|
2529
|
+
};
|
|
2530
|
+
},
|
|
2531
|
+
ListInputFieldsSchema
|
|
2532
|
+
);
|
|
2533
|
+
return {
|
|
2534
|
+
listInputFields,
|
|
2535
|
+
context: {
|
|
2536
|
+
meta: {
|
|
2537
|
+
listInputFields: {
|
|
2538
|
+
inputSchema: ListInputFieldsSchema
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
};
|
|
1883
2543
|
};
|
|
1884
2544
|
|
|
1885
|
-
// src/
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
2545
|
+
// src/plugins/request/index.ts
|
|
2546
|
+
function transformUrlToRelayPath(url) {
|
|
2547
|
+
const targetUrl = new URL(url);
|
|
2548
|
+
const relayPath = `/relay/${targetUrl.host}${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
|
|
2549
|
+
return relayPath;
|
|
2550
|
+
}
|
|
2551
|
+
var requestPlugin = ({ context }) => {
|
|
2552
|
+
const request = createFunction(async function request2(options) {
|
|
2553
|
+
const { api } = context;
|
|
2554
|
+
const {
|
|
2555
|
+
url,
|
|
2556
|
+
method = "GET",
|
|
2557
|
+
body,
|
|
2558
|
+
headers: optionsHeaders,
|
|
2559
|
+
authenticationId,
|
|
2560
|
+
callbackUrl,
|
|
2561
|
+
authenticationTemplate
|
|
2562
|
+
} = options;
|
|
2563
|
+
const relayPath = transformUrlToRelayPath(url);
|
|
2564
|
+
const headers = {};
|
|
2565
|
+
if (optionsHeaders) {
|
|
2566
|
+
const headerEntries = optionsHeaders instanceof Headers ? Array.from(optionsHeaders.entries()) : Array.isArray(optionsHeaders) ? optionsHeaders : Object.entries(optionsHeaders);
|
|
2567
|
+
for (const [key, value] of headerEntries) {
|
|
2568
|
+
headers[key] = value;
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
if (authenticationId) {
|
|
2572
|
+
headers["X-Relay-Authentication-Id"] = authenticationId.toString();
|
|
2573
|
+
}
|
|
2574
|
+
if (callbackUrl) {
|
|
2575
|
+
headers["X-Relay-Callback-Url"] = callbackUrl;
|
|
2576
|
+
}
|
|
2577
|
+
if (authenticationTemplate) {
|
|
2578
|
+
headers["X-Authentication-Template"] = authenticationTemplate;
|
|
2579
|
+
}
|
|
2580
|
+
return await api.fetch(relayPath, {
|
|
2581
|
+
method,
|
|
2582
|
+
body,
|
|
2583
|
+
headers
|
|
2584
|
+
});
|
|
2585
|
+
}, RelayRequestSchema);
|
|
2586
|
+
return {
|
|
2587
|
+
request,
|
|
2588
|
+
context: {
|
|
2589
|
+
meta: {
|
|
2590
|
+
request: {
|
|
2591
|
+
inputSchema: RelayRequestSchema
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
};
|
|
1890
2596
|
};
|
|
1891
2597
|
|
|
1892
2598
|
// src/sdk.ts
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
runAction: (options2) => runAction({ ...options2, api }),
|
|
1934
|
-
listAuthentications: (options2 = {}) => listAuthentications({ ...options2, api }),
|
|
1935
|
-
getAuthentication: (options2) => getAuthentication({ ...options2, api }),
|
|
1936
|
-
findFirstAuthentication: (options2 = {}) => findFirstAuthentication({ ...options2, api }),
|
|
1937
|
-
findUniqueAuthentication: (options2 = {}) => findUniqueAuthentication({ ...options2, api }),
|
|
1938
|
-
listFields: (options2) => listFields({ ...options2, api }),
|
|
1939
|
-
generateTypes: (options2) => generateTypes({ ...options2, api }),
|
|
1940
|
-
bundleCode: (options2) => bundleCode(options2),
|
|
1941
|
-
// No API config needed
|
|
1942
|
-
fetch: (options2) => fetch({ ...options2, api })
|
|
1943
|
-
};
|
|
1944
|
-
const fullSdk = {
|
|
1945
|
-
...baseSdk,
|
|
1946
|
-
// Add plugins - apps plugin gets the base SDK cast as full ZapierSdk type
|
|
1947
|
-
// This is safe because by the time plugin functions are called, fullSdk will be complete
|
|
1948
|
-
apps: createAppsPlugin({
|
|
1949
|
-
sdk: baseSdk
|
|
1950
|
-
})
|
|
2599
|
+
function createSdk(initialSdk = {}, initialContext = { meta: {} }) {
|
|
2600
|
+
return {
|
|
2601
|
+
...initialSdk,
|
|
2602
|
+
getContext: () => initialContext,
|
|
2603
|
+
addPlugin(plugin, options = {}) {
|
|
2604
|
+
const currentSdkWithContext = {
|
|
2605
|
+
...initialSdk,
|
|
2606
|
+
getContext: () => initialContext
|
|
2607
|
+
};
|
|
2608
|
+
const pluginResult = plugin({
|
|
2609
|
+
sdk: currentSdkWithContext,
|
|
2610
|
+
context: initialContext,
|
|
2611
|
+
...options
|
|
2612
|
+
});
|
|
2613
|
+
const { context: pluginContext, ...sdkProperties } = pluginResult;
|
|
2614
|
+
const newSdk = { ...initialSdk, ...sdkProperties };
|
|
2615
|
+
let newContext = {
|
|
2616
|
+
...initialContext,
|
|
2617
|
+
meta: initialContext.meta || {}
|
|
2618
|
+
};
|
|
2619
|
+
if (pluginContext) {
|
|
2620
|
+
const { meta: pluginMeta, ...otherPluginContext } = pluginContext;
|
|
2621
|
+
newContext = {
|
|
2622
|
+
...newContext,
|
|
2623
|
+
...otherPluginContext
|
|
2624
|
+
};
|
|
2625
|
+
if (pluginMeta) {
|
|
2626
|
+
newContext = {
|
|
2627
|
+
...newContext,
|
|
2628
|
+
meta: {
|
|
2629
|
+
...newContext.meta,
|
|
2630
|
+
// Existing meta (now guaranteed to exist)
|
|
2631
|
+
...pluginMeta
|
|
2632
|
+
// New meta from plugin
|
|
2633
|
+
}
|
|
2634
|
+
};
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
return createSdk(newSdk, newContext);
|
|
2638
|
+
}
|
|
1951
2639
|
};
|
|
1952
|
-
|
|
2640
|
+
}
|
|
2641
|
+
function createZapierSdk(options = {}) {
|
|
2642
|
+
return createSdk().addPlugin(apiPlugin, options).addPlugin(listAppsPlugin).addPlugin(getAppPlugin).addPlugin(listActionsPlugin).addPlugin(getActionPlugin).addPlugin(listInputFieldsPlugin).addPlugin(runActionPlugin).addPlugin(listAuthenticationsPlugin).addPlugin(getAuthenticationPlugin).addPlugin(findFirstAuthenticationPlugin).addPlugin(findUniqueAuthenticationPlugin).addPlugin(requestPlugin).addPlugin(fetchPlugin).addPlugin(appsPlugin).addPlugin(getProfilePlugin).addPlugin(registryPlugin);
|
|
1953
2643
|
}
|
|
1954
2644
|
|
|
1955
|
-
export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema,
|
|
2645
|
+
export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, appKeyResolver, appsPlugin, authenticationIdResolver, createSdk, createZapierSdk, fetchPlugin, formatErrorMessage, getResolutionOrder, getResolutionOrderForParams, getResolvableParams, getResolver, getResolversForMissingParams, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, hasResolver, inputsResolver, isPositional, resolverRegistry };
|