webflow-api 1.3.0 → 1.3.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.
Files changed (54) hide show
  1. package/dist/api/collection.d.ts +112 -0
  2. package/dist/api/collection.js +94 -0
  3. package/dist/api/index.d.ts +7 -0
  4. package/dist/api/index.js +23 -0
  5. package/dist/api/item.d.ts +177 -0
  6. package/dist/api/item.js +151 -0
  7. package/dist/api/meta.d.ts +53 -0
  8. package/dist/api/meta.js +25 -0
  9. package/dist/api/oauth.d.ts +71 -0
  10. package/dist/api/oauth.js +71 -0
  11. package/dist/api/site.d.ts +140 -0
  12. package/dist/api/site.js +137 -0
  13. package/dist/api/user.d.ts +143 -0
  14. package/dist/api/user.js +119 -0
  15. package/dist/api/webhook.d.ts +102 -0
  16. package/dist/api/webhook.js +80 -0
  17. package/dist/core/error.d.ts +21 -0
  18. package/dist/core/error.js +30 -0
  19. package/dist/core/index.d.ts +3 -0
  20. package/dist/core/index.js +19 -0
  21. package/dist/core/response.d.ts +32 -0
  22. package/dist/core/response.js +26 -0
  23. package/dist/core/webflow.d.ts +390 -0
  24. package/dist/core/webflow.js +518 -0
  25. package/dist/index.d.ts +2 -0
  26. package/package.json +7 -1
  27. package/yarn.lock +2840 -0
  28. package/.eslintrc +0 -31
  29. package/.github/workflows/code-quality.yml +0 -102
  30. package/.github/workflows/npm-publish.yml +0 -21
  31. package/.github/workflows/semgrep.yml +0 -24
  32. package/.prettierignore +0 -5
  33. package/.prettierrc +0 -6
  34. package/jest.config.js +0 -17
  35. package/tests/api/collection.test.ts +0 -147
  36. package/tests/api/item.test.ts +0 -180
  37. package/tests/api/meta.test.ts +0 -38
  38. package/tests/api/oauth.test.ts +0 -44
  39. package/tests/api/site.test.ts +0 -202
  40. package/tests/api/user.test.ts +0 -139
  41. package/tests/api/webhook.test.ts +0 -82
  42. package/tests/core/error.test.ts +0 -19
  43. package/tests/core/response.test.ts +0 -36
  44. package/tests/core/webflow.test.ts +0 -540
  45. package/tests/fixtures/collection.fixture.ts +0 -374
  46. package/tests/fixtures/index.ts +0 -7
  47. package/tests/fixtures/item.fixture.ts +0 -193
  48. package/tests/fixtures/meta.fixture.ts +0 -34
  49. package/tests/fixtures/oauth.fixture.ts +0 -38
  50. package/tests/fixtures/site.fixture.ts +0 -78
  51. package/tests/fixtures/user.fixture.ts +0 -175
  52. package/tests/fixtures/webhook.fixture.ts +0 -69
  53. package/tsconfig.eslint.json +0 -7
  54. package/tsconfig.json +0 -14
@@ -1,540 +0,0 @@
1
- import axios from "axios";
2
- import MockAdapter from "axios-mock-adapter";
3
- import { Webflow, RequestError, SupportedScope } from "../../src/core";
4
- import {
5
- MetaFixture,
6
- SiteFixture,
7
- ItemFixture,
8
- WebhookFixture,
9
- CollectionFixture,
10
- OAuthFixture,
11
- UserFixture,
12
- } from "../fixtures";
13
-
14
- describe("Webflow", () => {
15
- const options = { host: "test.com", token: "test" };
16
- const mock = new MockAdapter(axios);
17
- const webflow = new Webflow(options);
18
-
19
- afterEach(() => {
20
- mock.resetHistory();
21
- });
22
-
23
- describe("Instance", () => {
24
- it("should create a new instance of Webflow", () => {
25
- expect(() => new Webflow()).not.toThrowError();
26
- });
27
-
28
- it("should create a new instance of Webflow with options", () => {
29
- const options = { token: "token", host: "test.com" };
30
- const instance = new Webflow(options);
31
- expect(instance.options).toEqual(options);
32
- });
33
- });
34
-
35
- describe("Helpers", () => {
36
- it("should set the host", async () => {
37
- mock.onGet("/").reply(200, {});
38
- await webflow.get("/");
39
-
40
- expect(mock.history.get[0].baseURL).toBe(`https://api.${options.host}/`);
41
- });
42
-
43
- it("should set the authorization token", async () => {
44
- mock.onGet("/", "", { Authorization: `Bearer ${options.token}` }).reply(200, {});
45
- await webflow.get("/");
46
- });
47
- });
48
-
49
- describe("HTTP Methods", () => {
50
- it("should call GET", async () => {
51
- const query = { test: true };
52
- mock.onGet("/").reply(200, {});
53
- await webflow.get("/", query);
54
- expect(mock.history.get.length).toBe(1);
55
- expect(mock.history.get[0].params).toMatchObject(query);
56
- });
57
- it("should call DELETE", async () => {
58
- const query = { test: true };
59
- mock.onDelete("/").reply(200, {});
60
- await webflow.delete("/", query);
61
- expect(mock.history.delete.length).toBe(1);
62
- expect(mock.history.delete[0].params).toMatchObject(query);
63
- });
64
- it("should call POST", async () => {
65
- const query = { test: true };
66
- mock.onPost("/").reply(200, { body: true });
67
- await webflow.post("/", { body: true }, query);
68
- expect(mock.history.post.length).toBe(1);
69
- expect(mock.history.post[0].params).toMatchObject(query);
70
- });
71
- it("should call PUT", async () => {
72
- const query = { test: true };
73
- mock.onPut("/").reply(200, { body: true });
74
- await webflow.put("/", { body: true }, query);
75
- expect(mock.history.put.length).toBe(1);
76
- expect(mock.history.put[0].params).toMatchObject(query);
77
- });
78
- it("should call PATCH", async () => {
79
- const query = { test: true };
80
- mock.onPatch("/").reply(200, { body: true });
81
- await webflow.patch("/", { body: true }, query);
82
- expect(mock.history.patch.length).toBe(1);
83
- expect(mock.history.patch[0].params).toMatchObject(query);
84
- });
85
- it("should throw a RequestError when Webflow returns a 200 with error", async () => {
86
- mock.onGet("/").reply(200, {
87
- msg: "msg",
88
- code: 400,
89
- name: "name",
90
- path: "path",
91
- err: "err",
92
- });
93
-
94
- await expect(webflow.get("/")).rejects.toThrowError(RequestError);
95
- });
96
- });
97
-
98
- describe("API Calls", () => {
99
- describe("OAuth", () => {
100
- it("should generate an authorization url", () => {
101
- const { parameters } = OAuthFixture.authorize;
102
- const { client_id, state, response_type } = parameters;
103
-
104
- const url = webflow.authorizeUrl({ client_id, state });
105
- const query = new URLSearchParams({ response_type, client_id, state });
106
-
107
- expect(url).toBeDefined();
108
- expect(url).toBe(`https://${options.host}/oauth/authorize?${query.toString()}`);
109
- });
110
-
111
- it("should generate an authorization url with valid scopes", () => {
112
- const { parameters } = OAuthFixture.authorize;
113
- const { client_id, state, response_type } = parameters;
114
- const scopes: SupportedScope[] = ["assets:read", "cms:write"];
115
-
116
- const url = webflow.authorizeUrl({ client_id, state, scopes });
117
- const queryParts = [
118
- `response_type=${response_type}`,
119
- `client_id=${client_id}`,
120
- `state=${state}`,
121
- `scope=${scopes.join("+")}`,
122
- ];
123
- const query = queryParts.join("&");
124
-
125
- expect(url).toBeDefined();
126
- expect(url).toBe(`https://${options.host}/oauth/authorize?${query}`);
127
- });
128
-
129
- it("should generate an access token", async () => {
130
- const { parameters, response, path } = OAuthFixture.access_token;
131
-
132
- mock.onPost(path, parameters).reply(200, response);
133
- const result = await webflow.accessToken(parameters);
134
-
135
- expect(result).toBeDefined();
136
- expect(result.access_token).toBe(response.access_token);
137
- });
138
-
139
- it("should revoke an access token", async () => {
140
- const { parameters, response, path } = OAuthFixture.revoke_token;
141
-
142
- mock.onPost(path, parameters).reply(200, response);
143
- const result = await webflow.revokeToken(parameters);
144
-
145
- expect(result).toBeDefined();
146
- expect(result.didRevoke).toBe(true);
147
- });
148
- });
149
-
150
- describe("Meta", () => {
151
- it("should get info", async () => {
152
- const { response } = MetaFixture.info;
153
- const path = `/info`;
154
-
155
- mock.onGet(path).reply(200, response);
156
- const result = await webflow.info();
157
-
158
- expect(result).toBeDefined();
159
- expect(result.users).toEqual(response.users);
160
- expect(result.sites).toEqual(response.sites);
161
- expect(result.workspaces).toEqual(response.workspaces);
162
- expect(result.application).toEqual(response.application);
163
- });
164
-
165
- it("should get info about the user", async () => {
166
- const { response } = MetaFixture.installer;
167
-
168
- const path = `/user`;
169
- mock.onGet(path).reply(200, response);
170
- const result = await webflow.authenticatedUser();
171
-
172
- expect(result).toBeDefined();
173
- expect(result.user._id).toEqual(response.user._id);
174
- expect(result.user.email).toEqual(response.user.email);
175
- expect(result.user.firstName).toEqual(response.user.firstName);
176
- expect(result.user.lastName).toEqual(response.user.lastName);
177
- });
178
- });
179
-
180
- describe("Sites", () => {
181
- it("should respond with a list of sites", async () => {
182
- const { response } = SiteFixture.list;
183
- const path = "/sites";
184
-
185
- mock.onGet(path).reply(200, response);
186
- const sites = await webflow.sites();
187
-
188
- expect(sites).toBeDefined();
189
- expect(sites.length).toBe(response.length);
190
- expect(sites[0]._id).toBe(response[0]._id);
191
- });
192
-
193
- it("should respond with a single site", async () => {
194
- const { parameters, response } = SiteFixture.getOne;
195
- const { siteId } = parameters;
196
- const path = `/sites/${siteId}`;
197
-
198
- mock.onGet(path).reply(200, response);
199
- const site = await webflow.site(parameters);
200
-
201
- expect(site).toBeDefined();
202
- expect(site._id).toBe(siteId);
203
- });
204
-
205
- it("should respond with a list of domains", async () => {
206
- const { parameters, response } = SiteFixture.domains;
207
- const { siteId } = parameters;
208
- const path = `/sites/${siteId}/domains`;
209
-
210
- mock.onGet(path).reply(200, response);
211
- const domains = await webflow.domains(parameters);
212
-
213
- expect(domains).toBeDefined();
214
- expect(domains.length).toBe(response.length);
215
- expect(domains[0]).toMatchObject(response[0]);
216
- });
217
-
218
- it("should publish a site", async () => {
219
- const { parameters, response } = SiteFixture.publish;
220
- const { siteId, domains } = parameters;
221
- const path = `/sites/${siteId}/publish`;
222
-
223
- mock.onPost(path, { domains }).reply(200, response);
224
- const result = await webflow.publishSite(parameters);
225
-
226
- expect(result).toBeDefined();
227
- expect(result.queued).toBe(true);
228
- });
229
- });
230
-
231
- describe("Collections", () => {
232
- it("should respond with a list of site collections", async () => {
233
- const { parameters, response } = CollectionFixture.list;
234
- const { siteId } = parameters;
235
- const path = `/sites/${siteId}/collections`;
236
-
237
- mock.onGet(path).reply(200, response);
238
- const collections = await webflow.collections(parameters);
239
-
240
- expect(collections).toBeDefined();
241
- expect(collections.length).toBe(response.length);
242
- expect(collections[0]._id).toBe(response[0]._id);
243
- });
244
-
245
- it("should respond with a single site collection", async () => {
246
- const { parameters, response } = CollectionFixture.getOne;
247
- const { collectionId } = parameters;
248
- const path = `/collections/${collectionId}`;
249
-
250
- mock.onGet(path).reply(200, response);
251
- const collection = await webflow.collection(parameters);
252
-
253
- expect(collection).toBeDefined();
254
- expect(collection._id).toBe(response._id);
255
- });
256
- });
257
-
258
- describe("Items", () => {
259
- it("should respond with a list of items", async () => {
260
- const { parameters, response } = ItemFixture.list;
261
- const { collectionId } = parameters;
262
- const path = `/collections/${collectionId}/items`;
263
-
264
- mock.onGet(path).reply(200, response);
265
- const items = await webflow.items(parameters);
266
-
267
- expect(items).toBeDefined();
268
- expect(items.length).toBe(response.items.length);
269
- expect(items[0]._id).toBe(response.items[0]._id);
270
- });
271
-
272
- it("should respond with a list of paginated items", async () => {
273
- const { parameters, response } = ItemFixture.list;
274
- const { collectionId } = parameters;
275
-
276
- const limit = 2;
277
- const offset = 2;
278
- const path = `/collections/${collectionId}/items`;
279
-
280
- mock.onGet(path, { params: { limit, offset } }).reply(200, response);
281
- const items = await webflow.items({ ...parameters, limit, offset });
282
-
283
- expect(items).toBeDefined();
284
- expect(items.length).toBe(response.items.length);
285
- expect(items[0]._id).toBe(response.items[0]._id);
286
- });
287
-
288
- it("should respond with a single item", async () => {
289
- const { parameters, response } = ItemFixture.getOne;
290
- const { collectionId, itemId } = parameters;
291
- const path = `/collections/${collectionId}/items/${itemId}`;
292
-
293
- mock.onGet(path).reply(200, response);
294
- const item = await webflow.item(parameters);
295
-
296
- expect(item).toBeDefined();
297
- expect(item._id).toBe(response.items[0]._id);
298
- });
299
-
300
- it("should create an item", async () => {
301
- const { parameters, response } = ItemFixture.create;
302
- const { collectionId, fields } = parameters;
303
-
304
- const path = `/collections/${collectionId}/items`;
305
-
306
- mock.onPost(path, { fields }).reply(200, response);
307
- const item = await webflow.createItem(parameters);
308
-
309
- expect(item).toBeDefined();
310
- expect(item._id).toBe(response._id);
311
- });
312
-
313
- it("should update an item", async () => {
314
- const { parameters, response } = ItemFixture.update;
315
- const { collectionId, itemId } = parameters;
316
- const path = `/collections/${collectionId}/items/${itemId}`;
317
-
318
- mock.onPut(path).reply(200, response);
319
- const item = await webflow.updateItem(parameters);
320
-
321
- expect(item).toBeDefined();
322
- expect(item._id).toBe(response._id);
323
- });
324
-
325
- it("should patch an item", async () => {
326
- const { parameters, response } = ItemFixture.update;
327
- const { collectionId, itemId } = parameters;
328
- const path = `/collections/${collectionId}/items/${itemId}`;
329
-
330
- mock.onPatch(path).reply(200, response);
331
- const item = await webflow.patchItem(parameters);
332
-
333
- expect(item).toBeDefined();
334
- expect(item._id).toBe(response._id);
335
- });
336
-
337
- it("should remove an item", async () => {
338
- const { parameters, response } = ItemFixture.remove;
339
- const { collectionId, itemId } = parameters;
340
- const path = `/collections/${collectionId}/items/${itemId}`;
341
-
342
- mock.onDelete(path).reply(200, response);
343
- const item = await webflow.removeItem(parameters);
344
-
345
- expect(item).toBeDefined();
346
- expect(item.deleted).toBe(response.deleted);
347
- });
348
-
349
- it("should unpublish multiple items", async () => {
350
- const { parameters, response } = ItemFixture.unpublish;
351
- const { collectionId, itemIds } = parameters;
352
- const path = `/collections/${collectionId}/items`;
353
-
354
- mock.onDelete(path).reply(200, response);
355
- const result = await webflow.deleteItems(parameters);
356
-
357
- expect(result).toBeDefined();
358
- expect(result.deletedItemIds.length).toBe(itemIds.length);
359
- expect(result.deletedItemIds[0]).toBe(itemIds[0]);
360
- });
361
-
362
- it("should live unpublish multiple items", async () => {
363
- const { parameters, response } = ItemFixture.unpublish;
364
- const { collectionId, itemIds } = parameters;
365
- const path = `/collections/${collectionId}/items`;
366
-
367
- const { live } = parameters;
368
- mock.onDelete(path, { params: { live } }).reply(200, response);
369
- const result = await webflow.deleteItems(parameters);
370
-
371
- expect(result).toBeDefined();
372
- expect(result.deletedItemIds.length).toBe(itemIds.length);
373
- expect(result.deletedItemIds[0]).toBe(itemIds[0]);
374
- });
375
-
376
- it("should publish multiple items", async () => {
377
- const { parameters, response } = ItemFixture.publish;
378
- const { collectionId, itemIds } = parameters;
379
-
380
- const { live } = parameters;
381
- const path = `/collections/${collectionId}/items/publish`;
382
-
383
- mock.onPut(path, { itemIds }).reply(200, response);
384
- const result = await webflow.publishItems(parameters);
385
- expect(mock.history.put[0].params).toMatchObject({ live });
386
-
387
- expect(result).toBeDefined();
388
- expect(result.publishedItemIds.length).toBe(itemIds.length);
389
- expect(result.publishedItemIds[0]).toBe(itemIds[0]);
390
- });
391
-
392
- it("should live publish multiple items", async () => {
393
- const { parameters, response } = ItemFixture.publish;
394
- const { collectionId, itemIds } = parameters;
395
-
396
- const { live } = parameters;
397
- const path = `/collections/${collectionId}/items/publish`;
398
-
399
- mock.onPut(path, { itemIds }).reply(200, response);
400
- const result = await webflow.publishItems(parameters);
401
- expect(mock.history.put[0].params).toMatchObject({ live });
402
-
403
- expect(result).toBeDefined();
404
- expect(result.publishedItemIds.length).toBe(itemIds.length);
405
- expect(result.publishedItemIds[0]).toBe(itemIds[0]);
406
- });
407
- });
408
-
409
- describe("Memberships", () => {
410
- it("should respond with a list of users", async () => {
411
- const { response, parameters } = UserFixture.list;
412
- const { siteId } = parameters;
413
- const path = `/sites/${siteId}/users`;
414
-
415
- mock.onGet(path).reply(200, response);
416
- const users = await webflow.users(parameters);
417
-
418
- expect(users).toBeDefined();
419
- expect(users.length).toBe(response.users.length);
420
- expect(users[0]).toMatchObject(response.users[0]);
421
- });
422
-
423
- it("should respond with a single user", async () => {
424
- const { response, parameters } = UserFixture.getOne;
425
- const { siteId, userId } = parameters;
426
- const path = `/sites/${siteId}/users/${userId}`;
427
-
428
- mock.onGet(path).reply(200, response);
429
- const user = await webflow.user(parameters);
430
-
431
- expect(user).toBeDefined();
432
- expect(user._id).toBe(response._id);
433
- });
434
-
435
- it("should invite a user", async () => {
436
- const { response, parameters } = UserFixture.invite;
437
- const { siteId, email } = parameters;
438
- const path = `/sites/${siteId}/users/invite`;
439
-
440
- mock.onPost(path, { email }).reply(200, response);
441
- const user = await webflow.inviteUser(parameters);
442
-
443
- expect(user).toBeDefined();
444
- expect(user.data).toBeDefined();
445
- expect(user._id).toBe(response._id);
446
- expect(user.data).toMatchObject(response.data);
447
- });
448
-
449
- it("should update a user", async () => {
450
- const { response, parameters } = UserFixture.update;
451
- const { siteId, userId } = parameters;
452
- const path = `/sites/${siteId}/users/${userId}`;
453
-
454
- mock.onPatch(path).reply(200, response);
455
- const user = await webflow.updateUser(parameters);
456
-
457
- expect(user).toBeDefined();
458
- expect(user._id).toBe(response._id);
459
- expect(user.data).toBeDefined();
460
- expect(user.data).toMatchObject(response.data);
461
- });
462
-
463
- it("should remove a user", async () => {
464
- const { response, parameters } = UserFixture.delete;
465
- const { siteId, userId } = parameters;
466
- const path = `/sites/${siteId}/users/${userId}`;
467
-
468
- mock.onDelete(path).reply(200, response);
469
- const result = await webflow.removeUser(parameters);
470
-
471
- expect(result).toBeDefined();
472
- expect(result.deleted).toBe(response.deleted);
473
- });
474
-
475
- it("should respond with a list of access groups", async () => {
476
- const { response, parameters } = UserFixture.accessGroups;
477
- const { siteId } = parameters;
478
- const path = `/sites/${siteId}/accessgroups`;
479
-
480
- mock.onGet(path).reply(200, response);
481
- const result = await webflow.accessGroups(parameters);
482
-
483
- expect(result).toBeDefined();
484
- expect(result.accessGroups.length).toBe(response.accessGroups.length);
485
- expect(result.accessGroups[0]).toMatchObject(response.accessGroups[0]);
486
- });
487
- });
488
-
489
- describe("Webhooks", () => {
490
- it("should respond with a list of webhooks", async () => {
491
- const { parameters, response } = WebhookFixture.list;
492
- const { siteId } = parameters;
493
- const path = `/sites/${siteId}/webhooks`;
494
-
495
- mock.onGet(path).reply(200, response);
496
- const webhooks = await webflow.webhooks(parameters);
497
-
498
- expect(webhooks).toBeDefined();
499
- expect(webhooks.length).toEqual(response.length);
500
- expect(webhooks[0]).toMatchObject(response[0]);
501
- });
502
-
503
- it("should respond with a single webhook", async () => {
504
- const { parameters, response } = WebhookFixture.getOne;
505
- const { siteId, webhookId } = parameters;
506
-
507
- const path = `/sites/${siteId}/webhooks/${webhookId}`;
508
- mock.onGet(path).reply(200, response);
509
- const webhook = await webflow.webhook(parameters);
510
-
511
- expect(webhook).toBeDefined();
512
- expect(webhook._id).toBe(response._id);
513
- });
514
-
515
- it("should create a webhook", async () => {
516
- const { parameters, response } = WebhookFixture.create;
517
- const { siteId, triggerType, url } = parameters;
518
-
519
- const path = `/sites/${siteId}/webhooks`;
520
- mock.onPost(path, { triggerType, url }).reply(200, response);
521
- const webhook = await webflow.createWebhook(parameters);
522
-
523
- expect(webhook).toBeDefined();
524
- expect(webhook._id).toBe(response._id);
525
- });
526
-
527
- it("should remove a webhook", async () => {
528
- const { parameters, response } = WebhookFixture.delete;
529
- const { siteId, webhookId } = parameters;
530
-
531
- const path = `/sites/${siteId}/webhooks/${webhookId}`;
532
- mock.onDelete(path).reply(200, response);
533
- const result = await webflow.removeWebhook(parameters);
534
-
535
- expect(result).toBeDefined();
536
- expect(result.deleted).toEqual(response.deleted);
537
- });
538
- });
539
- });
540
- });