Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e01b166

Browse files
author
John Agan
authoredNov 1, 2022
Created V1.0 with OAuth support (#64)
* updated tests * bumped package version and added header overload * added automations * fixed tests * fixed tests * fixed dependencies * Fixed babel compile and updated readme * added oauth docs and endpoints * fixed linting rules * fixed readme typo * fixed readme typo * added installer to docs * added installer to docs * added tests for all wrappers * split up tests and removed yaml fixtures * corrected tests and build for CJS * removed default sec-fetch-mode
1 parent d3951b6 commit e01b166

33 files changed

+4659
-15206
lines changed
 

‎.babelrc

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
{
2-
"presets": ["@babel/preset-env"],
3-
"plugins": ["@babel/plugin-transform-modules-commonjs"],
4-
"env": {
5-
"development": {
6-
"sourceMaps": "inline"
7-
}
8-
}
9-
}
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"targets": {
7+
"node": true
8+
}
9+
}
10+
]
11+
],
12+
"plugins": ["add-module-exports"]
13+
}

‎.eslintrc

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
"extends": ["airbnb-base", "prettier"],
33
"plugins": ["prettier"],
44
"rules": {
5+
"camelcase": "off",
6+
"arrow-body-style": "off",
57
"no-underscore-dangle": 0,
68
"class-methods-use-this": 0,
9+
"max-classes-per-file": "off",
710
"prettier/prettier": ["error"]
8-
}
11+
},
12+
"ignorePatterns": ["node_modules/", "dist/"]
913
}

‎.github/workflows/main.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Tests
2+
3+
on: [push]
4+
5+
jobs:
6+
test:
7+
name: Tests
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
- uses: actions/setup-node@v3
12+
- run: yarn install
13+
- run: yarn test
14+
lint:
15+
name: Linter
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v3
19+
- uses: actions/setup-node@v3
20+
- run: yarn install
21+
- run: yarn test

‎README.md

+222-17
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,244 @@
11
# Webflow CMS API Client
22

3-
## Requirements
4-
5-
* Node.js 4+
6-
* NPM / YARN
7-
* Webpack / Browserify (optional)
8-
93
## Installation
104

11-
Install the package via NPM or YARN:
5+
Using npm:
126

137
```shell
14-
$ npm install --save webflow-api
8+
$ npm install webflow-api
9+
```
1510

11+
using yarn
12+
```
1613
$ yarn add webflow-api
1714
```
1815

1916
## Usage
17+
The constructor takes in a few optional parameters to initialize the API client
18+
19+
* `token` - the access token to use
20+
* `headers` - additional headers to add to the request
21+
* `version` - the version of the API you wish to use
22+
* `mode` - the [sec-fetch-mode](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode) to use
23+
24+
``` javascript
25+
const Webflow = require("webflow-api");
26+
27+
// initialize the client with the access token
28+
const webflow = new Webflow({ token: "[ACCESS TOKEN]" });
29+
30+
// fully loaded
31+
const webflow = new Webflow({
32+
token: "[ACCESS TOKEN]"
33+
version: "1.0.0",
34+
mode: "cors",
35+
headers: {
36+
"User-Agent": "My Webflow App / 1.0"
37+
}
38+
});
39+
```
40+
## Basic Usage
41+
### Chaining Calls
42+
You can retrieve child resources by chaining calls on the parent object.
43+
44+
```javascript
45+
// get the first site
46+
const [site] = await webflow.sites();
47+
48+
// get the first collection in the site
49+
const [collection] = await site.collections();
50+
51+
// get the first item in the collection
52+
const [item] = await collection.items();
53+
54+
// get one item from the collection
55+
const item = await collection.items({ itemId: "[ITEM ID]" });
56+
```
57+
58+
### Pagination
59+
To paginate results, pass in the `limit` and `offset` options.
60+
61+
```javascript
62+
// Get the first page of results
63+
const page1 = await collection.items({ limit: 20 });
64+
65+
// Get the second page of results
66+
const page2 = await collection.items({ limit: 20, offset: 20 });
67+
```
68+
69+
### Rate Limit
70+
Check rate limit status on each call by checking the `_meta` property.
71+
72+
```javascript
73+
// make an api call
74+
const site = await webflow.site({ siteId: "[SITE ID]" });
75+
76+
// check rate limit
77+
const { rateLimit } = site._meta; // { limit: 60, remaining: 56 }
78+
```
79+
### Update Token
80+
If you need to update the access token, you can set the `token` property at any time.
81+
82+
```javascript
83+
// token is unset
84+
const webflow = new Webflow();
85+
86+
// set token
87+
webflow.token = "[ACCESS TOKEN]";
88+
```
89+
### Calling APIs Directly
90+
All Webflow API endpoints can be called directly using the `get`, `post`, `put`, and `delete` methods.
2091

2192
```javascript
22-
const Webflow = require('webflow-api');
93+
// call the sites endpoint directly
94+
const sites = await webflow.get("/sites");
95+
96+
// post to an endpoint directly
97+
const result = await webflow.post("/sites/[SITE ID]/publish", {
98+
domains: ["hello-webflow.com"]
99+
});
100+
```
101+
102+
## OAuth
103+
To implement OAuth, you'll need a Webflow App registered and a webserver running, that is publicly facing.
23104

24-
// Initialize the API
25-
const api = new Webflow({ token: 'api-token' });
105+
### Authorize
106+
The first step in OAuth is to generate an authorization url to redirect the user to.
26107

27-
// Fetch a site
28-
api.site({ siteId: '580e63e98c9a982ac9b8b741' }).then(site => console.log(site));
108+
```javascript
109+
// Get the authorization url to redirect users to
110+
const url = webflow.authorizeUrl({
111+
client_id: "[CLIENT ID]",
112+
state: "1234567890", // optional
113+
redirect_uri: "https://my.server.com/oauth/callback" // optional
114+
});
115+
116+
// redirect user from your server route
117+
res.redirect(url);
29118
```
30119

31-
The `Webflow` constructor takes several options to initialize the API client:
120+
### Access Token
121+
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.
122+
123+
```javascript
124+
const auth = await webflow.accessToken({
125+
client_id,
126+
client_secret,
127+
code,
128+
redirect_uri // optional - required if used in the authorize step
129+
});
130+
131+
// you now have the user's access token to make API requests with
132+
const userWF = new Webflow({ token: auth.access_token });
133+
134+
// pull information for the installer
135+
const installer = await userWF.installer();
136+
```
32137

33-
* `token` - the API token **(required)**
34-
* `version` - the version of the API you wish to use (optional)
138+
### Revoke Token
139+
If the user decides to disconnect from your server, you should call revoke token to remove the authorization.
140+
141+
```javascript
142+
const result = await webflow.revokeToken({
143+
client_id,
144+
client_secret,
145+
access_token
146+
});
147+
148+
// ensure it went through
149+
if (result.didRevoke) {
150+
// should equal true
151+
}
152+
```
153+
154+
## Examples
155+
### Sites
156+
Get all sites available or lookup by site id.
157+
158+
```javascript
159+
// List all sites
160+
const sites = await webflow.sites();
161+
162+
// Get a single site
163+
const site = await webflow.sites({ siteId: "[SITE ID]" });
164+
```
165+
166+
### Collections
167+
Get all collections available for a site or lookup by collection id.
168+
```javascript
169+
// Get a site's collection from the site
170+
const collections = await site.collections();
171+
172+
// Get a site's collection by passing in a site id
173+
const collections = await webflow.collections({ siteId: "[SITE ID]" });
174+
175+
// Get a single collection
176+
const collection = await webflow.collection({ collectionId: "[COLLECTION ID]" });
177+
```
178+
179+
### Collection Items
180+
Get all collection items available for a collection or lookup by item id.
181+
```javascript
182+
// Get the items from a collection
183+
const items = await collection.items();
184+
185+
// Get a subset of items
186+
const items = await collection.items({ limit: 10, offset: 2 });
187+
188+
// Get a single item
189+
const item = await webflow.item({ collectionId: "[COLLECTION ID]", itemId: "[ITEM ID]" });
190+
```
191+
### Update an Item
192+
```javascript
193+
// Set the fields to update
194+
const fields = {
195+
name: "New Name",
196+
_archived: false,
197+
_draft: false,
198+
slug: "new-name",
199+
};
200+
201+
// call update
202+
const updatedItem = await webflow.updateItem({
203+
collectionId: "[COLLECTION ID]",
204+
itemId: "[ITEM ID]",
205+
fields,
206+
});
207+
```
208+
209+
### Memberships
210+
```javascript
211+
// Get the all users for a site
212+
const users = await webflow.users({
213+
siteId: "[SITE ID]"
214+
});
215+
216+
// Get a single user
217+
const user = await site.user({
218+
siteId: "[SITE ID]",
219+
userId: "[USER ID]"
220+
});
221+
```
222+
223+
### Webhooks
224+
```javascript
225+
// get webhooks for a site
226+
const webhooks = await site.webhooks();
227+
228+
// create a webhook
229+
const webhook = await site.createWebhook({
230+
triggerType: "form_submission",
231+
url: "https://webhook.site"
232+
});
233+
234+
```
235+
236+
### Installer
237+
```javascript
238+
// pull information for the installer
239+
const installer = await webflow.installer();
240+
```
35241

36-
All of the API methods are documented in the [API documentation](https://developers.webflow.com).
37242

38243
## Contributing
39244

‎circle.yml

-27
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.