webflow-api 1.2.2 → 1.3.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/.eslintrc +31 -0
- package/.github/workflows/code-quality.yml +102 -0
- package/.github/workflows/npm-publish.yml +21 -0
- package/.github/workflows/semgrep.yml +24 -0
- package/.prettierignore +5 -0
- package/.prettierrc +6 -0
- package/README.md +50 -1
- package/jest.config.js +17 -0
- package/package.json +2 -7
- package/src/api/collection.ts +1 -1
- package/src/api/item.ts +4 -4
- package/src/api/meta.ts +2 -2
- package/src/api/oauth.ts +8 -2
- package/src/core/error.ts +1 -1
- package/src/core/webflow.ts +111 -4
- package/tests/api/collection.test.ts +147 -0
- package/tests/api/item.test.ts +180 -0
- package/tests/api/meta.test.ts +38 -0
- package/tests/api/oauth.test.ts +44 -0
- package/tests/api/site.test.ts +202 -0
- package/tests/api/user.test.ts +139 -0
- package/tests/api/webhook.test.ts +82 -0
- package/tests/core/error.test.ts +19 -0
- package/tests/core/response.test.ts +36 -0
- package/tests/core/webflow.test.ts +540 -0
- package/tests/fixtures/collection.fixture.ts +374 -0
- package/tests/fixtures/index.ts +7 -0
- package/tests/fixtures/item.fixture.ts +193 -0
- package/tests/fixtures/meta.fixture.ts +34 -0
- package/tests/fixtures/oauth.fixture.ts +38 -0
- package/tests/fixtures/site.fixture.ts +78 -0
- package/tests/fixtures/user.fixture.ts +175 -0
- package/tests/fixtures/webhook.fixture.ts +69 -0
- package/tsconfig.eslint.json +7 -0
- package/tsconfig.json +14 -0
- package/dist/api/collection.d.ts +0 -112
- package/dist/api/collection.js +0 -94
- package/dist/api/index.d.ts +0 -7
- package/dist/api/index.js +0 -23
- package/dist/api/item.d.ts +0 -177
- package/dist/api/item.js +0 -151
- package/dist/api/meta.d.ts +0 -53
- package/dist/api/meta.js +0 -25
- package/dist/api/oauth.d.ts +0 -69
- package/dist/api/oauth.js +0 -66
- package/dist/api/site.d.ts +0 -140
- package/dist/api/site.js +0 -137
- package/dist/api/user.d.ts +0 -143
- package/dist/api/user.js +0 -119
- package/dist/api/webhook.d.ts +0 -102
- package/dist/api/webhook.js +0 -80
- package/dist/core/error.d.ts +0 -21
- package/dist/core/error.js +0 -30
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.js +0 -19
- package/dist/core/response.d.ts +0 -32
- package/dist/core/response.js +0 -26
- package/dist/core/webflow.d.ts +0 -386
- package/dist/core/webflow.js +0 -445
- package/dist/index.d.ts +0 -2
- package/yarn.lock +0 -2830
package/.eslintrc
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"es2021": true,
|
|
4
|
+
"browser": true
|
|
5
|
+
},
|
|
6
|
+
"extends": [
|
|
7
|
+
"eslint:recommended",
|
|
8
|
+
"plugin:@typescript-eslint/recommended",
|
|
9
|
+
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
|
10
|
+
],
|
|
11
|
+
"parser": "@typescript-eslint/parser",
|
|
12
|
+
"parserOptions": {
|
|
13
|
+
"ecmaVersion": 12,
|
|
14
|
+
"project": "tsconfig.eslint.json"
|
|
15
|
+
},
|
|
16
|
+
"plugins": ["@typescript-eslint", "prettier"],
|
|
17
|
+
"rules": {
|
|
18
|
+
"prefer-const": "error",
|
|
19
|
+
"prettier/prettier": "error",
|
|
20
|
+
"@typescript-eslint/no-unused-vars": "off",
|
|
21
|
+
"@typescript-eslint/no-unused-params": "off",
|
|
22
|
+
"@typescript-eslint/no-unsafe-argument": "warn",
|
|
23
|
+
"@typescript-eslint/no-unsafe-assignment": "warn"
|
|
24
|
+
},
|
|
25
|
+
"overrides": [
|
|
26
|
+
{
|
|
27
|
+
"env": { "jest": true, "node": true },
|
|
28
|
+
"files": ["tests/**/*.ts"]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: Code Quality
|
|
2
|
+
|
|
3
|
+
on: push
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
name: TypeScript Build
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout
|
|
12
|
+
uses: actions/checkout@v2
|
|
13
|
+
|
|
14
|
+
- name: Install Node.js
|
|
15
|
+
uses: actions/setup-node@v1
|
|
16
|
+
with:
|
|
17
|
+
node-version: 14.x
|
|
18
|
+
|
|
19
|
+
- name: yarn install
|
|
20
|
+
run: yarn install
|
|
21
|
+
|
|
22
|
+
- run: yarn build
|
|
23
|
+
name: yarn build
|
|
24
|
+
|
|
25
|
+
typecheck:
|
|
26
|
+
name: TypeScript Typecheck
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@v2
|
|
32
|
+
|
|
33
|
+
- name: Install Node.js
|
|
34
|
+
uses: actions/setup-node@v1
|
|
35
|
+
with:
|
|
36
|
+
node-version: 14.x
|
|
37
|
+
|
|
38
|
+
- name: yarn install
|
|
39
|
+
run: yarn install
|
|
40
|
+
|
|
41
|
+
- run: yarn typecheck
|
|
42
|
+
name: yarn typecheck
|
|
43
|
+
|
|
44
|
+
test:
|
|
45
|
+
name: Jest CI Tests
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
|
|
48
|
+
steps:
|
|
49
|
+
- name: Checkout
|
|
50
|
+
uses: actions/checkout@v2
|
|
51
|
+
|
|
52
|
+
- name: Install Node.js
|
|
53
|
+
uses: actions/setup-node@v1
|
|
54
|
+
with:
|
|
55
|
+
node-version: 14.x
|
|
56
|
+
|
|
57
|
+
- name: yarn install
|
|
58
|
+
run: yarn install
|
|
59
|
+
|
|
60
|
+
- name: yarn build
|
|
61
|
+
run: yarn build
|
|
62
|
+
|
|
63
|
+
- run: yarn test:ci
|
|
64
|
+
name: yarn test:ci
|
|
65
|
+
|
|
66
|
+
prettier:
|
|
67
|
+
name: Prettier Formatting
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
|
|
70
|
+
steps:
|
|
71
|
+
- name: Checkout
|
|
72
|
+
uses: actions/checkout@v2
|
|
73
|
+
|
|
74
|
+
- name: Install Node.js
|
|
75
|
+
uses: actions/setup-node@v1
|
|
76
|
+
with:
|
|
77
|
+
node-version: 14.x
|
|
78
|
+
|
|
79
|
+
- name: yarn install
|
|
80
|
+
run: yarn install
|
|
81
|
+
|
|
82
|
+
- run: yarn format:check
|
|
83
|
+
name: yarn format:check
|
|
84
|
+
|
|
85
|
+
lint:
|
|
86
|
+
name: ESLint Linting
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
|
|
89
|
+
steps:
|
|
90
|
+
- name: Checkout
|
|
91
|
+
uses: actions/checkout@v2
|
|
92
|
+
|
|
93
|
+
- name: Install Node.js
|
|
94
|
+
uses: actions/setup-node@v1
|
|
95
|
+
with:
|
|
96
|
+
node-version: 14.x
|
|
97
|
+
|
|
98
|
+
- name: yarn install
|
|
99
|
+
run: yarn install
|
|
100
|
+
|
|
101
|
+
- run: yarn lint
|
|
102
|
+
name: yarn lint
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Publish to NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [created]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish-npm:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v3
|
|
12
|
+
- uses: actions/setup-node@v3
|
|
13
|
+
with:
|
|
14
|
+
node-version: 16
|
|
15
|
+
registry-url: https://registry.npmjs.org/
|
|
16
|
+
- run: |
|
|
17
|
+
yarn install
|
|
18
|
+
yarn test
|
|
19
|
+
yarn publish
|
|
20
|
+
env:
|
|
21
|
+
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
on:
|
|
2
|
+
workflow_dispatch: {}
|
|
3
|
+
pull_request: {}
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
- master
|
|
8
|
+
paths:
|
|
9
|
+
- .github/workflows/semgrep.yml
|
|
10
|
+
schedule:
|
|
11
|
+
# random HH:MM to avoid a load spike on GitHub Actions at 00:00
|
|
12
|
+
- cron: 34 11 * * *
|
|
13
|
+
name: Semgrep
|
|
14
|
+
jobs:
|
|
15
|
+
semgrep:
|
|
16
|
+
name: semgrep/ci
|
|
17
|
+
runs-on: ubuntu-20.04
|
|
18
|
+
env:
|
|
19
|
+
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
|
|
20
|
+
container:
|
|
21
|
+
image: returntocorp/semgrep
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v3
|
|
24
|
+
- run: semgrep ci
|
package/.prettierignore
ADDED
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -38,6 +38,41 @@ const webflow = new Webflow({
|
|
|
38
38
|
});
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## Transitioning to API v2
|
|
42
|
+
|
|
43
|
+
We're actively working on a new version of the SDK that will fully support API v2. In the meantime, to make use of API v2 with our SDK, there are some important changes you need to be aware of:
|
|
44
|
+
|
|
45
|
+
### Setting Up For API v2
|
|
46
|
+
|
|
47
|
+
When initializing your client, it's crucial to set the `beta` flag to true in the client options. This ensures you're targeting the API v2 endpoints.
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
const webflow = new Webflow({ beta: true, ...otherOptions });
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Please note, when the beta flag is set, several built-in methods will not be available. These methods include, but are not limited to, info, authenticatedUser, sites, site, etc. Attempting to use these will throw an error.
|
|
54
|
+
|
|
55
|
+
### Calling API v2 Endpoints
|
|
56
|
+
|
|
57
|
+
To interact with API v2, you'll need to move away from using built-in methods, and instead use the provided HTTP methods directly.
|
|
58
|
+
|
|
59
|
+
For instance, where you previously used `sites()`:
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// get the first site
|
|
63
|
+
const [site] = await webflow.sites();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For API v2, you will need to use direct HTTP methods:
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// get the first site
|
|
70
|
+
const sites = await webflow.get("/sites");
|
|
71
|
+
const site = sites[0];
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
We understand that this is a shift in how you interact with the SDK, but rest assured, our upcoming SDK version will streamline this process and offer a more integrated experience with API v2.
|
|
75
|
+
|
|
41
76
|
## Basic Usage
|
|
42
77
|
|
|
43
78
|
### Chaining Calls
|
|
@@ -131,6 +166,20 @@ const url = webflow.authorizeUrl({
|
|
|
131
166
|
res.redirect(url);
|
|
132
167
|
```
|
|
133
168
|
|
|
169
|
+
### Using the scopes Parameter with v2 API
|
|
170
|
+
|
|
171
|
+
The v2 API introduces the concept of 'scopes', providing more control over app permissions. Instead of using the scope parameter as a single string, you can define multiple permissions using the scopes array:
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
const url = webflow.authorizeUrl({
|
|
175
|
+
client_id: "[CLIENT ID]",
|
|
176
|
+
redirect_uri: "https://my.server.com/oauth/callback",
|
|
177
|
+
scopes: ["read:sites", "write:items", "read:users"],
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
For more information and a detailed list of available scopes, refer to our Scopes Guide.
|
|
182
|
+
|
|
134
183
|
### Access Token
|
|
135
184
|
|
|
136
185
|
Once a user has authorized their Webflow resource(s), Webflow will redirect back to your server with a `code`. Use this to get an access token.
|
|
@@ -176,7 +225,7 @@ Get all sites available or lookup by site id.
|
|
|
176
225
|
const sites = await webflow.sites();
|
|
177
226
|
|
|
178
227
|
// Get a single site
|
|
179
|
-
const site = await webflow.
|
|
228
|
+
const site = await webflow.site({ siteId: "[SITE ID]" });
|
|
180
229
|
```
|
|
181
230
|
|
|
182
231
|
### Collections
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
|
2
|
+
module.exports = {
|
|
3
|
+
// A preset that is used as a base for Jest's configuration
|
|
4
|
+
preset: "ts-jest",
|
|
5
|
+
|
|
6
|
+
// The test environment that will be used for testing
|
|
7
|
+
testEnvironment: "node",
|
|
8
|
+
|
|
9
|
+
// A map from regular expressions to paths to transformers
|
|
10
|
+
transform: { "^.+\\.ts?$": "ts-jest" },
|
|
11
|
+
|
|
12
|
+
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
|
|
13
|
+
transformIgnorePatterns: ["<rootDir>/node_modules/"],
|
|
14
|
+
|
|
15
|
+
// Automatically clear mock calls, instances, contexts and results before every test
|
|
16
|
+
clearMocks: true,
|
|
17
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webflow-api",
|
|
3
3
|
"description": "Webflow's official Node.js SDK for Data APIs",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"contributors": [
|
|
8
|
+
"Rodney Urquhart (https://github.com/rodneyu215)",
|
|
8
9
|
"John Agan (https://github.com/johnagan)"
|
|
9
10
|
],
|
|
10
11
|
"repository": {
|
|
@@ -12,12 +13,6 @@
|
|
|
12
13
|
"type": "git"
|
|
13
14
|
},
|
|
14
15
|
"license": "MIT",
|
|
15
|
-
"files": [
|
|
16
|
-
"dist",
|
|
17
|
-
"src",
|
|
18
|
-
"LICENSE",
|
|
19
|
-
"yarn.lock"
|
|
20
|
-
],
|
|
21
16
|
"scripts": {
|
|
22
17
|
"test": "yarn build && jest",
|
|
23
18
|
"build": "yarn clean && tsc",
|
package/src/api/collection.ts
CHANGED
|
@@ -32,7 +32,7 @@ export type CollectionField = {
|
|
|
32
32
|
required: boolean;
|
|
33
33
|
editable: boolean;
|
|
34
34
|
// TODO: add a better type
|
|
35
|
-
validations?: Record<string,
|
|
35
|
+
validations?: Record<string, any>;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
/**************************************************************
|
package/src/api/item.ts
CHANGED
|
@@ -36,7 +36,7 @@ export interface IDeletedItems {
|
|
|
36
36
|
/**************************************************************
|
|
37
37
|
* Types
|
|
38
38
|
**************************************************************/
|
|
39
|
-
export type
|
|
39
|
+
export type PaginatedItems = PaginatedData & {
|
|
40
40
|
items: IItem[];
|
|
41
41
|
};
|
|
42
42
|
|
|
@@ -77,7 +77,7 @@ export class Item extends WebflowRecord<IItem> implements IItem {
|
|
|
77
77
|
requireArgs({ collectionId, itemId });
|
|
78
78
|
const path = `/collections/${collectionId}/items/${itemId}`;
|
|
79
79
|
// The API returns a paginated list with one record :(
|
|
80
|
-
return client.get<
|
|
80
|
+
return client.get<PaginatedItems>(path);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
@@ -96,7 +96,7 @@ export class Item extends WebflowRecord<IItem> implements IItem {
|
|
|
96
96
|
requireArgs({ collectionId });
|
|
97
97
|
const params = { limit, offset };
|
|
98
98
|
const path = `/collections/${collectionId}/items`;
|
|
99
|
-
return client.get<
|
|
99
|
+
return client.get<PaginatedItems>(path, { params });
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
@@ -192,7 +192,7 @@ export class Item extends WebflowRecord<IItem> implements IItem {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
/**
|
|
195
|
-
*
|
|
195
|
+
* Unpublish a list of Items
|
|
196
196
|
* @param params The params for the request
|
|
197
197
|
* @param params.collectionId The Collection ID
|
|
198
198
|
* @param params.live Unpublish from the live site
|
package/src/api/meta.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface IAuthenticatedUser {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export interface
|
|
27
|
+
export interface IAuthenticationInfo {
|
|
28
28
|
application: InfoApplication;
|
|
29
29
|
workspaces: string[];
|
|
30
30
|
rateLimit: number;
|
|
@@ -48,7 +48,7 @@ export class Meta {
|
|
|
48
48
|
* @returns The authentication info
|
|
49
49
|
*/
|
|
50
50
|
static info(client: AxiosInstance) {
|
|
51
|
-
return client.get<
|
|
51
|
+
return client.get<IAuthenticationInfo>("/info");
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
package/src/api/oauth.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
|
-
import { requireArgs } from "../core";
|
|
2
|
+
import { requireArgs, SupportedScope } from "../core";
|
|
3
3
|
|
|
4
4
|
/**************************************************************
|
|
5
5
|
* Interfaces
|
|
@@ -7,6 +7,7 @@ import { requireArgs } from "../core";
|
|
|
7
7
|
export interface IAuthorizeUrlParams {
|
|
8
8
|
state?: string;
|
|
9
9
|
scope?: string;
|
|
10
|
+
scopes?: SupportedScope[];
|
|
10
11
|
client_id: string;
|
|
11
12
|
redirect_uri?: string;
|
|
12
13
|
response_type?: string;
|
|
@@ -52,15 +53,20 @@ export class OAuth {
|
|
|
52
53
|
* @returns The URL to authorize a user
|
|
53
54
|
*/
|
|
54
55
|
static authorizeUrl(
|
|
55
|
-
{ response_type = "code", redirect_uri, client_id, state, scope }: IAuthorizeUrlParams,
|
|
56
|
+
{ response_type = "code", redirect_uri, client_id, state, scope, scopes }: IAuthorizeUrlParams,
|
|
56
57
|
client: AxiosInstance,
|
|
57
58
|
) {
|
|
58
59
|
requireArgs({ client_id });
|
|
59
60
|
|
|
61
|
+
if (scope && scopes) {
|
|
62
|
+
throw new Error("Please provide either 'scope' or 'scopes', but not both.");
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
const params = { response_type, client_id };
|
|
61
66
|
if (redirect_uri) params["redirect_uri"] = redirect_uri;
|
|
62
67
|
if (state) params["state"] = state;
|
|
63
68
|
if (scope) params["scope"] = scope;
|
|
69
|
+
if (scopes && scopes.length > 0) params["scope"] = scopes.join("+");
|
|
64
70
|
|
|
65
71
|
const url = "/oauth/authorize";
|
|
66
72
|
const baseURL = client.defaults.baseURL.replace("api.", "");
|
package/src/core/error.ts
CHANGED
|
@@ -16,7 +16,7 @@ export class RequestError extends Error implements IRequestError {
|
|
|
16
16
|
err: string;
|
|
17
17
|
|
|
18
18
|
constructor(error: IRequestError) {
|
|
19
|
-
super(error.err ? error.err : "Unknown error
|
|
19
|
+
super(error.err ? error.err : "Unknown error occurred");
|
|
20
20
|
Object.assign(this, error);
|
|
21
21
|
}
|
|
22
22
|
}
|
package/src/core/webflow.ts
CHANGED
|
@@ -22,8 +22,51 @@ export interface Options {
|
|
|
22
22
|
token?: string;
|
|
23
23
|
version?: string;
|
|
24
24
|
headers?: Record<string, string>;
|
|
25
|
+
beta?: boolean;
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
type MethodNames =
|
|
29
|
+
| "info"
|
|
30
|
+
| "authenticatedUser"
|
|
31
|
+
| "sites"
|
|
32
|
+
| "site"
|
|
33
|
+
| "publishSite"
|
|
34
|
+
| "domains"
|
|
35
|
+
| "collections"
|
|
36
|
+
| "collection"
|
|
37
|
+
| "items"
|
|
38
|
+
| "item"
|
|
39
|
+
| "createItem"
|
|
40
|
+
| "updateItem"
|
|
41
|
+
| "patchItem"
|
|
42
|
+
| "removeItem"
|
|
43
|
+
| "deleteItems"
|
|
44
|
+
| "publishItems";
|
|
45
|
+
|
|
46
|
+
export const SCOPES_ARRAY = [
|
|
47
|
+
"assets:read",
|
|
48
|
+
"assets:write",
|
|
49
|
+
"authorized_user:read",
|
|
50
|
+
"cms:read",
|
|
51
|
+
"cms:write",
|
|
52
|
+
"custom_code:read",
|
|
53
|
+
"custom_code:write",
|
|
54
|
+
"forms:read",
|
|
55
|
+
"forms:write",
|
|
56
|
+
"pages:read",
|
|
57
|
+
"pages:write",
|
|
58
|
+
"sites:read",
|
|
59
|
+
"sites:write",
|
|
60
|
+
"users:read",
|
|
61
|
+
"users:write",
|
|
62
|
+
"ecommerce:read",
|
|
63
|
+
"ecommerce:write",
|
|
64
|
+
] as const;
|
|
65
|
+
|
|
66
|
+
export type SupportedScope = typeof SCOPES_ARRAY[number];
|
|
67
|
+
|
|
68
|
+
type ParamValueType = string | number | boolean | null | undefined;
|
|
69
|
+
|
|
27
70
|
/**************************************************************
|
|
28
71
|
* Class
|
|
29
72
|
**************************************************************/
|
|
@@ -32,6 +75,43 @@ export class Webflow {
|
|
|
32
75
|
constructor(public options: Options = {}) {
|
|
33
76
|
this.client = axios.create(this.config);
|
|
34
77
|
this.client.interceptors.response.use(ErrorInterceptor);
|
|
78
|
+
|
|
79
|
+
if (this.options.beta) {
|
|
80
|
+
this.removeNonBetaMethods();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private removeNonBetaMethods() {
|
|
85
|
+
const methodsToRemove: MethodNames[] = [
|
|
86
|
+
"info",
|
|
87
|
+
"authenticatedUser",
|
|
88
|
+
"sites",
|
|
89
|
+
"site",
|
|
90
|
+
"publishSite",
|
|
91
|
+
"domains",
|
|
92
|
+
"collections",
|
|
93
|
+
"collection",
|
|
94
|
+
"items",
|
|
95
|
+
"item",
|
|
96
|
+
"createItem",
|
|
97
|
+
"updateItem",
|
|
98
|
+
"patchItem",
|
|
99
|
+
"removeItem",
|
|
100
|
+
"deleteItems",
|
|
101
|
+
"publishItems",
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
methodsToRemove.forEach((method) => {
|
|
105
|
+
Object.defineProperty(this, method, {
|
|
106
|
+
value: function (): never {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`The method '${method}()' is not available in beta mode. Please disable the beta option to use this method.`,
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
enumerable: false,
|
|
112
|
+
configurable: true,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
35
115
|
}
|
|
36
116
|
|
|
37
117
|
// Set the Authentication token
|
|
@@ -46,10 +126,11 @@ export class Webflow {
|
|
|
46
126
|
|
|
47
127
|
// The Axios configuration
|
|
48
128
|
get config() {
|
|
49
|
-
const { host = DEFAULT_HOST, token, version, headers } = this.options;
|
|
129
|
+
const { host = DEFAULT_HOST, token, version, headers, beta = false } = this.options;
|
|
130
|
+
const effectiveHost = beta ? "webflow.com/beta" : host;
|
|
50
131
|
|
|
51
132
|
const config: AxiosRequestConfig = {
|
|
52
|
-
baseURL: `https://api.${
|
|
133
|
+
baseURL: `https://api.${effectiveHost}/`,
|
|
53
134
|
headers: {
|
|
54
135
|
"Content-Type": "application/json",
|
|
55
136
|
"User-Agent": USER_AGENT,
|
|
@@ -63,6 +144,32 @@ export class Webflow {
|
|
|
63
144
|
// Add the Authorization header if a token is set
|
|
64
145
|
if (token) config.headers.Authorization = `Bearer ${token}`;
|
|
65
146
|
|
|
147
|
+
config.paramsSerializer = {
|
|
148
|
+
serialize: (params: Record<string, ParamValueType>): string => {
|
|
149
|
+
if (typeof params !== "object" || params === null) {
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const parts: string[] = [];
|
|
154
|
+
|
|
155
|
+
for (const key in params) {
|
|
156
|
+
const value = params[key];
|
|
157
|
+
if (value === undefined) continue;
|
|
158
|
+
|
|
159
|
+
const safeValue =
|
|
160
|
+
typeof value === "string" || typeof value === "number" ? value : String(value);
|
|
161
|
+
|
|
162
|
+
if (key === "scope") {
|
|
163
|
+
parts.push(`${key}=${safeValue}`);
|
|
164
|
+
} else {
|
|
165
|
+
parts.push(`${key}=${encodeURIComponent(safeValue)}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return parts.join("&");
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
|
|
66
173
|
return config;
|
|
67
174
|
}
|
|
68
175
|
|
|
@@ -328,7 +435,7 @@ export class Webflow {
|
|
|
328
435
|
return res.data;
|
|
329
436
|
}
|
|
330
437
|
/**
|
|
331
|
-
*
|
|
438
|
+
* Unpublish a Collection Item
|
|
332
439
|
* @param params The Item information
|
|
333
440
|
* @param params.collectionId The Collection ID
|
|
334
441
|
* @param params.itemId The Item ID
|
|
@@ -503,7 +610,7 @@ export class Webflow {
|
|
|
503
610
|
* @param params.siteId The Site Id
|
|
504
611
|
* @param params.url The Url the Webhook should call on events
|
|
505
612
|
* @param params.triggerType The type of event that should trigger the Webhook
|
|
506
|
-
* @param params.filter The filter to apply to the Webhook (
|
|
613
|
+
* @param params.filter The filter to apply to the Webhook (form_submission only)
|
|
507
614
|
* @returns The created webhook
|
|
508
615
|
*/
|
|
509
616
|
async createWebhook({
|