@zapier/zapier-sdk 0.4.1 → 0.5.1
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 +13 -0
- package/README.md +343 -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 +2108 -1379
- package/dist/index.d.mts +2440 -620
- package/dist/index.d.ts +17 -892
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.mjs +2093 -1362
- 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 +394 -171
- package/src/api/debug.ts +10 -1
- package/src/api/index.ts +0 -2
- package/src/api/polling.ts +28 -7
- package/src/api/schemas.ts +387 -0
- package/src/api/types.ts +72 -136
- package/src/constants.ts +10 -0
- package/src/index.ts +40 -19
- package/src/plugins/api/index.ts +47 -0
- package/src/plugins/apps/index.ts +25 -19
- package/src/plugins/apps/types.ts +7 -11
- package/src/plugins/fetch/index.ts +48 -40
- 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/{functions → plugins}/request/schemas.ts +20 -9
- 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 +132 -102
- 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 +70 -48
- 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/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/request/index.ts +0 -150
- package/src/functions/request/info.ts +0 -11
- 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/plugins/fetch/types.ts +0 -2
- /package/src/{schema-utils.ts → utils/schema-utils.ts} +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { createFunction, createPaginatedFunction } from "./function-utils";
|
|
3
|
+
import { ZapierValidationError, ZapierUnknownError } from "../types/errors";
|
|
4
|
+
import { ALL_ITEMS, listTestItems } from "./pagination-utils.test";
|
|
5
|
+
describe("createFunction", () => {
|
|
6
|
+
it("should return result from core function", async () => {
|
|
7
|
+
const mockCoreFn = async (options) => {
|
|
8
|
+
return `Hello, ${options.name}!`;
|
|
9
|
+
};
|
|
10
|
+
const wrappedFn = createFunction(mockCoreFn);
|
|
11
|
+
const result = await wrappedFn({ name: "World" });
|
|
12
|
+
expect(result).toBe("Hello, World!");
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe.each([
|
|
16
|
+
{ name: "createFunction", createFn: createFunction },
|
|
17
|
+
{ name: "createPaginatedFunction", createFn: createPaginatedFunction },
|
|
18
|
+
])("$name", ({ createFn }) => {
|
|
19
|
+
it("should preserve function name", async () => {
|
|
20
|
+
async function testCoreFn(options) {
|
|
21
|
+
return options.value * 2;
|
|
22
|
+
}
|
|
23
|
+
const wrappedFn = createFn(testCoreFn);
|
|
24
|
+
expect(wrappedFn.name).toBe("testCoreFn");
|
|
25
|
+
});
|
|
26
|
+
it("should normalize and rethrow ZapierError instances", async () => {
|
|
27
|
+
const mockError = new ZapierValidationError("Validation failed", {
|
|
28
|
+
details: { field: "name" },
|
|
29
|
+
});
|
|
30
|
+
const mockCoreFn = async () => {
|
|
31
|
+
throw mockError;
|
|
32
|
+
};
|
|
33
|
+
const wrappedFn = createFn(mockCoreFn);
|
|
34
|
+
await expect(wrappedFn({})).rejects.toBe(mockError);
|
|
35
|
+
});
|
|
36
|
+
it("should normalize generic Error to ZapierUnknownError", async () => {
|
|
37
|
+
const mockCoreFn = async () => {
|
|
38
|
+
throw new Error("Something went wrong");
|
|
39
|
+
};
|
|
40
|
+
const wrappedFn = createFn(mockCoreFn);
|
|
41
|
+
await expect(wrappedFn({})).rejects.toThrow(ZapierUnknownError);
|
|
42
|
+
});
|
|
43
|
+
it("should normalize non-Error values to ZapierUnknownError", async () => {
|
|
44
|
+
const mockCoreFn = async () => {
|
|
45
|
+
throw "String error";
|
|
46
|
+
};
|
|
47
|
+
const wrappedFn = createFn(mockCoreFn);
|
|
48
|
+
await expect(wrappedFn({})).rejects.toThrow(ZapierUnknownError);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("createPaginatedFunction", () => {
|
|
52
|
+
it("should wrap non-array result in {data: [result]}", async () => {
|
|
53
|
+
const mockCoreFn = async (options) => {
|
|
54
|
+
return `Hello, ${options.name}!`;
|
|
55
|
+
};
|
|
56
|
+
const wrappedFn = createPaginatedFunction(mockCoreFn);
|
|
57
|
+
const result = await wrappedFn({ name: "World" });
|
|
58
|
+
expect(result).toEqual({ data: ["Hello, World!"] });
|
|
59
|
+
});
|
|
60
|
+
it("should wrap array result in {data: result}", async () => {
|
|
61
|
+
const mockCoreFn = async (options) => {
|
|
62
|
+
return Array.from({ length: options.count }, (_, i) => `Item ${i + 1}`);
|
|
63
|
+
};
|
|
64
|
+
const wrappedFn = createPaginatedFunction(mockCoreFn);
|
|
65
|
+
const result = await wrappedFn({ count: 3 });
|
|
66
|
+
expect(result).toEqual({ data: ["Item 1", "Item 2", "Item 3"] });
|
|
67
|
+
});
|
|
68
|
+
it("should return {data} object unchanged", async () => {
|
|
69
|
+
const mockCoreFn = async (options) => {
|
|
70
|
+
return { data: options.items };
|
|
71
|
+
};
|
|
72
|
+
const wrappedFn = createPaginatedFunction(mockCoreFn);
|
|
73
|
+
const result = await wrappedFn({ items: ["A", "B", "C"] });
|
|
74
|
+
expect(result).toEqual({ data: ["A", "B", "C"] });
|
|
75
|
+
});
|
|
76
|
+
it("should allow for await iteration over pages", async () => {
|
|
77
|
+
const listItems = createPaginatedFunction(listTestItems);
|
|
78
|
+
const pages = [];
|
|
79
|
+
for await (const page of listItems({ pageSize: 3 })) {
|
|
80
|
+
pages.push(page);
|
|
81
|
+
if (pages.length >= 3)
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
// Should have collected 3 pages
|
|
85
|
+
expect(pages).toHaveLength(3);
|
|
86
|
+
// Check first page structure
|
|
87
|
+
expect(pages[0]).toEqual({
|
|
88
|
+
data: ALL_ITEMS.slice(0, 3),
|
|
89
|
+
nextCursor: "cursor-3",
|
|
90
|
+
});
|
|
91
|
+
// Check second page
|
|
92
|
+
expect(pages[1]).toEqual({
|
|
93
|
+
data: ALL_ITEMS.slice(3, 6),
|
|
94
|
+
nextCursor: "cursor-6",
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
it("should allow for await iteration over individual items", async () => {
|
|
98
|
+
const listItems = createPaginatedFunction(listTestItems);
|
|
99
|
+
const items = [];
|
|
100
|
+
for await (const item of listItems({ pageSize: 3 }).items()) {
|
|
101
|
+
items.push(item);
|
|
102
|
+
if (items.length >= 7)
|
|
103
|
+
break; // Get first 7 items across pages
|
|
104
|
+
}
|
|
105
|
+
// Should have collected 7 individual items
|
|
106
|
+
expect(items).toHaveLength(7);
|
|
107
|
+
// Should be the first 7 items from ALL_ITEMS (flattened from pages)
|
|
108
|
+
expect(items).toEqual(ALL_ITEMS.slice(0, 7));
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
type TPageOptions<TOptions> = TOptions extends undefined ? {
|
|
2
|
+
cursor?: string;
|
|
3
|
+
maxItems?: number;
|
|
4
|
+
pageSize?: number;
|
|
5
|
+
} : TOptions & {
|
|
6
|
+
cursor?: string;
|
|
7
|
+
maxItems?: number;
|
|
8
|
+
pageSize?: number;
|
|
9
|
+
};
|
|
10
|
+
export declare function createPrefixedCursor(prefix: string, cursor: string | undefined): string;
|
|
11
|
+
export declare function splitPrefixedCursor(cursor: string | undefined, prefixes?: string[]): [string | undefined, string | undefined];
|
|
12
|
+
/**
|
|
13
|
+
* Utility for paginating through API endpoints that return cursor-based pages
|
|
14
|
+
*
|
|
15
|
+
* @param pageFunction - Function that fetches a single page with {data, nextCursor} structure
|
|
16
|
+
* @param pageOptions - Options to pass to the page function (cursor will be managed automatically)
|
|
17
|
+
* @returns Async iterator that yields pages
|
|
18
|
+
*/
|
|
19
|
+
export declare function paginateMaxItems<TOptions, TPage extends {
|
|
20
|
+
data: any[];
|
|
21
|
+
nextCursor?: string;
|
|
22
|
+
}>(pageFunction: (options: TOptions & {
|
|
23
|
+
cursor?: string;
|
|
24
|
+
maxItems?: number;
|
|
25
|
+
pageSize?: number;
|
|
26
|
+
}) => Promise<TPage>, pageOptions?: TPageOptions<TOptions>): AsyncIterableIterator<TPage>;
|
|
27
|
+
export declare function paginateBuffered<TOptions, TPage extends {
|
|
28
|
+
data: any[];
|
|
29
|
+
nextCursor?: string;
|
|
30
|
+
}>(pageFunction: (options: TOptions & {
|
|
31
|
+
cursor?: string;
|
|
32
|
+
maxItems?: number;
|
|
33
|
+
pageSize?: number;
|
|
34
|
+
}) => Promise<TPage>, pageOptions?: TPageOptions<TOptions>): AsyncIterableIterator<TPage>;
|
|
35
|
+
export declare const paginate: typeof paginateBuffered;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=pagination-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-utils.d.ts","sourceRoot":"","sources":["../../src/utils/pagination-utils.ts"],"names":[],"mappings":"AAEA,KAAK,YAAY,CAAC,QAAQ,IAAI,QAAQ,SAAS,SAAS,GACpD;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD,QAAQ,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAoCzE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,CAKR;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,CAkB1C;AAED;;;;;;GAMG;AACH,wBAAuB,gBAAgB,CACrC,QAAQ,EACR,KAAK,SAAS;IAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAElD,YAAY,EAAE,CACZ,OAAO,EAAE,QAAQ,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KACE,OAAO,CAAC,KAAK,CAAC,EACnB,WAAW,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,GACnC,qBAAqB,CAAC,KAAK,CAAC,CAoC9B;AAED,wBAAuB,gBAAgB,CACrC,QAAQ,EACR,KAAK,SAAS;IAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAElD,YAAY,EAAE,CACZ,OAAO,EAAE,QAAQ,GAAG;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KACE,OAAO,CAAC,KAAK,CAAC,EACnB,WAAW,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,GACnC,qBAAqB,CAAC,KAAK,CAAC,CAiG9B;AAED,eAAO,MAAM,QAAQ,yBAAmB,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const offsetCursorMarker = "$$offset$$";
|
|
2
|
+
function splitOffsetCursor(cursor) {
|
|
3
|
+
if (!cursor) {
|
|
4
|
+
return [0, cursor];
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
const parsedCursor = JSON.parse(cursor);
|
|
8
|
+
if (!Array.isArray(parsedCursor)) {
|
|
9
|
+
return [0, cursor];
|
|
10
|
+
}
|
|
11
|
+
const [marker, offset, currentCursor] = parsedCursor;
|
|
12
|
+
if (marker !== offsetCursorMarker) {
|
|
13
|
+
return [0, cursor];
|
|
14
|
+
}
|
|
15
|
+
if (typeof offset !== "number") {
|
|
16
|
+
return [0, cursor];
|
|
17
|
+
}
|
|
18
|
+
return [offset, currentCursor];
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [0, cursor];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function createOffsetCursor(offset, currentCursor) {
|
|
25
|
+
return JSON.stringify([offsetCursorMarker, offset, currentCursor]);
|
|
26
|
+
}
|
|
27
|
+
export function createPrefixedCursor(prefix, cursor) {
|
|
28
|
+
if (!cursor) {
|
|
29
|
+
return `${prefix}::`;
|
|
30
|
+
}
|
|
31
|
+
return `${prefix}::${cursor}`;
|
|
32
|
+
}
|
|
33
|
+
export function splitPrefixedCursor(cursor, prefixes) {
|
|
34
|
+
if (!cursor) {
|
|
35
|
+
return [undefined, undefined];
|
|
36
|
+
}
|
|
37
|
+
const [prefix, ...rest] = cursor.split("::");
|
|
38
|
+
if (prefixes && !prefixes.includes(prefix)) {
|
|
39
|
+
return [undefined, cursor];
|
|
40
|
+
}
|
|
41
|
+
cursor = rest.join("::");
|
|
42
|
+
if (!cursor) {
|
|
43
|
+
return [prefix, undefined];
|
|
44
|
+
}
|
|
45
|
+
return [prefix, cursor];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Utility for paginating through API endpoints that return cursor-based pages
|
|
49
|
+
*
|
|
50
|
+
* @param pageFunction - Function that fetches a single page with {data, nextCursor} structure
|
|
51
|
+
* @param pageOptions - Options to pass to the page function (cursor will be managed automatically)
|
|
52
|
+
* @returns Async iterator that yields pages
|
|
53
|
+
*/
|
|
54
|
+
export async function* paginateMaxItems(pageFunction, pageOptions) {
|
|
55
|
+
let cursor = pageOptions?.cursor;
|
|
56
|
+
let totalItemsYielded = 0;
|
|
57
|
+
const maxItems = pageOptions?.maxItems;
|
|
58
|
+
const pageSize = pageOptions?.pageSize;
|
|
59
|
+
do {
|
|
60
|
+
const options = {
|
|
61
|
+
...(pageOptions || {}),
|
|
62
|
+
cursor,
|
|
63
|
+
pageSize: maxItems !== undefined && pageSize !== undefined
|
|
64
|
+
? Math.min(pageSize, maxItems)
|
|
65
|
+
: pageSize,
|
|
66
|
+
};
|
|
67
|
+
const page = await pageFunction(options);
|
|
68
|
+
if (maxItems !== undefined) {
|
|
69
|
+
const remainingItems = maxItems - totalItemsYielded;
|
|
70
|
+
if (page.data.length >= remainingItems) {
|
|
71
|
+
const yieldedPage = {
|
|
72
|
+
...page,
|
|
73
|
+
data: page.data.slice(0, remainingItems),
|
|
74
|
+
nextCursor: undefined,
|
|
75
|
+
};
|
|
76
|
+
yield yieldedPage;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
yield page;
|
|
81
|
+
totalItemsYielded += page.data.length;
|
|
82
|
+
cursor = page.nextCursor;
|
|
83
|
+
} while (cursor);
|
|
84
|
+
}
|
|
85
|
+
export async function* paginateBuffered(pageFunction, pageOptions) {
|
|
86
|
+
const pageSize = pageOptions?.pageSize;
|
|
87
|
+
const [cursorOffset, currentCursor] = splitOffsetCursor(pageOptions?.cursor);
|
|
88
|
+
const options = {
|
|
89
|
+
...(pageOptions || {}),
|
|
90
|
+
cursor: currentCursor,
|
|
91
|
+
};
|
|
92
|
+
const iterator = paginateMaxItems(pageFunction, options);
|
|
93
|
+
let bufferedPages = [];
|
|
94
|
+
let isFirstPage = true;
|
|
95
|
+
let cursor;
|
|
96
|
+
for await (let page of iterator) {
|
|
97
|
+
if (isFirstPage) {
|
|
98
|
+
isFirstPage = false;
|
|
99
|
+
if (cursorOffset) {
|
|
100
|
+
page = {
|
|
101
|
+
...page,
|
|
102
|
+
data: page.data.slice(cursorOffset),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (!pageSize) {
|
|
107
|
+
yield page;
|
|
108
|
+
cursor = page.nextCursor;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const bufferedLength = bufferedPages.reduce((acc, page) => acc + page.data.length, 0);
|
|
112
|
+
// If we don't have enough to fill a page, buffer this page.
|
|
113
|
+
if (bufferedLength + page.data.length < pageSize) {
|
|
114
|
+
bufferedPages.push(page);
|
|
115
|
+
cursor = page.nextCursor;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
// Let's yield a page from our buffered pages.
|
|
119
|
+
const bufferedItems = bufferedPages.map((p) => p.data).flat();
|
|
120
|
+
const allItems = [...bufferedItems, ...page.data];
|
|
121
|
+
const pageItems = allItems.slice(0, pageSize);
|
|
122
|
+
const remainingItems = allItems.slice(pageItems.length);
|
|
123
|
+
// No extra items to buffer, so we can just yield a normal page with a cursor to the next one.
|
|
124
|
+
if (remainingItems.length === 0) {
|
|
125
|
+
yield {
|
|
126
|
+
...page,
|
|
127
|
+
data: pageItems,
|
|
128
|
+
nextCursor: page.nextCursor,
|
|
129
|
+
};
|
|
130
|
+
bufferedPages = [];
|
|
131
|
+
cursor = page.nextCursor;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// Yield our items with a cursor to offset into this page.
|
|
135
|
+
yield {
|
|
136
|
+
...page,
|
|
137
|
+
data: pageItems,
|
|
138
|
+
nextCursor: createOffsetCursor(page.data.length - remainingItems.length, cursor),
|
|
139
|
+
};
|
|
140
|
+
while (remainingItems.length > pageSize) {
|
|
141
|
+
const pageItems = remainingItems.splice(0, pageSize);
|
|
142
|
+
yield {
|
|
143
|
+
...page,
|
|
144
|
+
data: pageItems,
|
|
145
|
+
nextCursor: createOffsetCursor(page.data.length - remainingItems.length, cursor),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
bufferedPages = [
|
|
149
|
+
{
|
|
150
|
+
...page,
|
|
151
|
+
data: remainingItems,
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
cursor = page.nextCursor;
|
|
155
|
+
}
|
|
156
|
+
if (bufferedPages.length > 0) {
|
|
157
|
+
const lastBufferedPage = bufferedPages.slice(-1)[0];
|
|
158
|
+
const bufferedItems = bufferedPages.map((p) => p.data).flat();
|
|
159
|
+
yield {
|
|
160
|
+
...lastBufferedPage,
|
|
161
|
+
data: bufferedItems,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export const paginate = paginateBuffered;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const ALL_ITEMS: {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
}[];
|
|
5
|
+
export declare function listTestItems(options: {
|
|
6
|
+
pageSize?: number;
|
|
7
|
+
cursor?: string;
|
|
8
|
+
filter?: string;
|
|
9
|
+
maxItems?: number;
|
|
10
|
+
}): Promise<{
|
|
11
|
+
data: {
|
|
12
|
+
id: number;
|
|
13
|
+
name: string;
|
|
14
|
+
}[];
|
|
15
|
+
nextCursor: string | undefined;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=pagination-utils.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-utils.test.d.ts","sourceRoot":"","sources":["../../src/utils/pagination-utils.test.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS;;;GAGnB,CAAC;AAGJ,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;;;;;;GA6CA"}
|