sharetribe-flex-sdk 1.14.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.
Files changed (87) hide show
  1. package/.circleci/config.yml +22 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.js +19 -0
  4. package/CHANGELOG.md +231 -0
  5. package/LICENSE +201 -0
  6. package/README.md +76 -0
  7. package/build/sharetribe-flex-sdk-node.js +13592 -0
  8. package/build/sharetribe-flex-sdk-web.js +1 -0
  9. package/docs/README.md +20 -0
  10. package/docs/authentication.md +179 -0
  11. package/docs/calling-the-api.md +217 -0
  12. package/docs/configurations.md +95 -0
  13. package/docs/developing-sdk.md +131 -0
  14. package/docs/docpress.json +14 -0
  15. package/docs/features.md +14 -0
  16. package/docs/keep-alive.md +48 -0
  17. package/docs/object-query-parameters.md +36 -0
  18. package/docs/scripts.js +41 -0
  19. package/docs/serializing-types-to-json.md +40 -0
  20. package/docs/sharing-session-between-client-and-server.md +19 -0
  21. package/docs/styles.css +95 -0
  22. package/docs/token-store.md +114 -0
  23. package/docs/try-it-in-browser.md +32 -0
  24. package/docs/try-it-in-the-playground.md +153 -0
  25. package/docs/types.md +27 -0
  26. package/docs/writing-your-own-token-store.md +29 -0
  27. package/docs/your-own-types.md +61 -0
  28. package/examples/README.md +5 -0
  29. package/examples/getting-started-browser/README.md +22 -0
  30. package/examples/getting-started-browser/index.html +89 -0
  31. package/examples/getting-started-browser/index.js +156 -0
  32. package/examples/getting-started-browser/screenshots/screenshot1.png +0 -0
  33. package/examples/getting-started-browser/screenshots/screenshot2.png +0 -0
  34. package/examples/getting-started-node/README.md +23 -0
  35. package/examples/getting-started-node/index.js +139 -0
  36. package/examples/getting-started-node/screenshots/screenshot.png +0 -0
  37. package/package.json +83 -0
  38. package/playground.js +295 -0
  39. package/src/browser_cookie_store.js +26 -0
  40. package/src/context_runner.js +151 -0
  41. package/src/context_runner.test.js +185 -0
  42. package/src/detect.js +11 -0
  43. package/src/express_cookie_store.js +57 -0
  44. package/src/fake/adapter.js +130 -0
  45. package/src/fake/api.js +137 -0
  46. package/src/fake/auth.js +84 -0
  47. package/src/fake/token_store.js +231 -0
  48. package/src/index.js +25 -0
  49. package/src/interceptors/.eslintrc.js +5 -0
  50. package/src/interceptors/add_auth_header.js +32 -0
  51. package/src/interceptors/add_auth_header.test.js +50 -0
  52. package/src/interceptors/add_auth_token_response.js +16 -0
  53. package/src/interceptors/add_client_id_to_params.js +12 -0
  54. package/src/interceptors/add_client_secret_to_params.js +15 -0
  55. package/src/interceptors/add_grant_type_to_params.js +23 -0
  56. package/src/interceptors/add_idp_client_id_to_params.js +17 -0
  57. package/src/interceptors/add_idp_id_to_params.js +17 -0
  58. package/src/interceptors/add_idp_token_to_params.js +17 -0
  59. package/src/interceptors/add_scope_to_params.js +18 -0
  60. package/src/interceptors/add_subject_token_to_params.js +18 -0
  61. package/src/interceptors/add_token_exchange_grant_type_to_params.js +12 -0
  62. package/src/interceptors/auth_info.js +50 -0
  63. package/src/interceptors/clear_token_after_revoke.js +45 -0
  64. package/src/interceptors/default_params.js +12 -0
  65. package/src/interceptors/fetch_auth_token_from_api.js +33 -0
  66. package/src/interceptors/fetch_auth_token_from_store.js +27 -0
  67. package/src/interceptors/fetch_refresh_token_for_revoke.js +24 -0
  68. package/src/interceptors/multipart_request.js +35 -0
  69. package/src/interceptors/retry_with_anon_token.js +58 -0
  70. package/src/interceptors/retry_with_refresh_token.js +70 -0
  71. package/src/interceptors/save_token.js +20 -0
  72. package/src/interceptors/transit_request.js +27 -0
  73. package/src/interceptors/transit_request.test.js +58 -0
  74. package/src/interceptors/transit_response.js +27 -0
  75. package/src/memory_store.js +19 -0
  76. package/src/params_serializer.js +65 -0
  77. package/src/params_serializer.test.js +58 -0
  78. package/src/sdk.js +894 -0
  79. package/src/sdk.test.js +908 -0
  80. package/src/serializer.js +279 -0
  81. package/src/serializer.test.js +229 -0
  82. package/src/token_store.js +15 -0
  83. package/src/types.js +108 -0
  84. package/src/types.test.js +75 -0
  85. package/src/utils.js +68 -0
  86. package/src/utils.test.js +85 -0
  87. package/webpack.config.babel.js +47 -0
@@ -0,0 +1,61 @@
1
+ # Your own types
2
+
3
+ In case you are using your own types or types from external library,
4
+ the SDK provides a way to convert the SDK types to and from your own
5
+ types.
6
+
7
+ The conversion is handled by "type handlers". You need to pass
8
+ `typeHandlers` when you create a new SDK instance.
9
+
10
+ A type handler is an object containing the following properties:
11
+
12
+ | Property | Description |
13
+ | -------- | ----------- |
14
+ | `sdkType` | The SDK type. |
15
+ | `appType` | The application specific type to convert SDK type to/from. |
16
+ | `canHandle` | A predicate function (i.e. function that returns truthy or falsy) that defines whether the this handler should be used. The SDK makes sure that `canHandle` will be called only for not `null` Object values, thus `null` check can be safely omitted.|
17
+ | `reader` | Conversion function. Gets an instance of `sdkType` as an argument, should return instance of `appType`. |
18
+ | `writer` | Conversion function. Gets an instance of `appType` as an argument, should return instance of `sdkType`. |
19
+
20
+ Either `appType` or `canHandle` should be provider, but not both.
21
+
22
+ Please note: v1.4.0 renamed `type` to `sdkType` and `customType` to `appType`.
23
+
24
+ **Example:** Convert
25
+ [`google.maps.LatLng`](https://developers.google.com/maps/documentation/javascript/reference/3/#LatLng)
26
+ to/from `LatLng`, [Decimal.js](https://github.com/MikeMcl/decimal.js/)
27
+ `Decimal` to/from `BigDecimal` and own plain object UUID
28
+ representation to UUID type class instance.
29
+
30
+ ```js
31
+ const { BigDecimal, LatLng } = require('sharetribe-flex-sdk').types;
32
+
33
+ const sdk = createInstance({
34
+ clientId: config.sdk.clientId,
35
+ baseUrl: config.sdk.baseUrl,
36
+ typeHandlers: [
37
+ {
38
+ sdkType: BigDecimal,
39
+ appType: Decimal,
40
+ writer: v => new BigDecimal(v.toString()),
41
+ reader: v => new Decimal(v.value),
42
+ },
43
+ sdkType: LatLng,
44
+ appType: google.maps.LatLng,
45
+ writer: v => new LatLng(v.lat(), v.lng()),
46
+ reader: v => new google.maps.LatLng(v.lat, v.lng)
47
+ },
48
+ {
49
+ sdkType: UUID,
50
+ canHandle: v => v.isMyOwnUuidType,
51
+ writer: v => new UUID(v.myOwnUuidValue),
52
+ reader: v => ({myOwnUuidValue: v.uuid,
53
+ isMyOwnUuidType: true})
54
+ }
55
+ ]
56
+ });
57
+ ```
58
+
59
+ **Caveat:** Only body parameters are converted. An error *Don't know
60
+ how to serialize query parameter* will be thrown if query parameters
61
+ contain your own types.
@@ -0,0 +1,5 @@
1
+ # Examples
2
+
3
+ [Getting started (Node.js)](./getting-started-node)
4
+
5
+ [Getting started (browser)](./getting-started-browser)
@@ -0,0 +1,22 @@
1
+ # Getting started example (browser)
2
+
3
+ This example shows how to query listings using the SDK, in browser.
4
+
5
+ ## Requirements
6
+
7
+ * Client ID
8
+
9
+ ## How to run the example:
10
+
11
+ ```
12
+ $ cd [project-root]
13
+ $ yarn install
14
+ $ yarn run build
15
+ $ cd examples/getting-started-browser
16
+ $ open index.html
17
+ ```
18
+
19
+ ## Screenshots
20
+
21
+ ![Screenshot1](screenshots/screenshot1.png)
22
+ ![Screenshot2](screenshots/screenshot2.png)
@@ -0,0 +1,89 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Getting started example</title>
5
+ <style>
6
+ body {
7
+ font-family: Helvetica,Arial,sans-serif;
8
+ margin: 50px;
9
+ }
10
+ .section {
11
+ margin-bottom: 50px;
12
+ }
13
+ label {
14
+ display: inline-block;
15
+ width: 100px;
16
+ }
17
+ input[type=text] {
18
+ width: 300px;
19
+ }
20
+ img {
21
+ margin-right: 20px;
22
+ margin-bottom: 20px;
23
+ }
24
+ </style>
25
+ </head>
26
+ <body>
27
+
28
+ <div class="main"></div>
29
+
30
+ <template class="form">
31
+ <h1>Getting started example</h1>
32
+
33
+ <p>Please type your <strong>Client ID</strong> and click <strong>Submit</strong></p>
34
+
35
+ <form>
36
+ <p>
37
+ <label for="client-id">Client ID</label>
38
+ <input type="text" id="client-id" name="client_id">
39
+ </p>
40
+ <p>
41
+ <input type="submit">
42
+ </p>
43
+ </form>
44
+ </template>
45
+
46
+ <template class="status">
47
+ <div class="section">
48
+ <h2>Response status</h3>
49
+
50
+ <p>Status: <span class="status-status"></span></p>
51
+ </div>
52
+ </template>
53
+
54
+ <template class="meta">
55
+ <div class="section">
56
+ <h2>Response meta</h3>
57
+
58
+ <p>Total items: <span class="meta-total-items"></span></p>
59
+ <p>Page: <span class="meta-page"></span></p>
60
+ <p>Images per page: <span class="meta-per-page"></span></p>
61
+ </div>
62
+ </template>
63
+
64
+ <template class="listings">
65
+ <div class="section">
66
+ <h2>Response data</h2>
67
+ <div class="listings-listings"></div>
68
+ </div>
69
+ </template>
70
+
71
+ <template class="listing">
72
+ <div>
73
+ <h3 class="listing-title"></h3>
74
+
75
+ <p>ID: <span class="listing-id"></span></p>
76
+ <p>Geolocation: <span class="listing-geolocation"></span></p>
77
+ <p>Created at: <span class="listing-created-at"></span></p>
78
+ <p>State: <span class="listing-state"></span></p>
79
+
80
+ <div class="listing-images"></div>
81
+
82
+ </div>
83
+ </template>
84
+
85
+ <script src="../../build/sharetribe-flex-sdk-web.js"></script>
86
+ <script src="./index.js"></script>
87
+ </body>
88
+
89
+ </html>
@@ -0,0 +1,156 @@
1
+ /* eslint-env browser */
2
+ /* global sharetribeSdk */
3
+
4
+ (() => {
5
+ //
6
+ // Helpers
7
+ //
8
+
9
+ const parseParams = qs => {
10
+ if (qs && qs.length) {
11
+ return qs
12
+ .substr(1)
13
+ .split('&')
14
+ .reduce((params, kv) => {
15
+ const [k, v] = kv.split('=');
16
+ return Object.assign({}, params, { [k]: decodeURIComponent(v) });
17
+ }, {});
18
+ }
19
+
20
+ return {};
21
+ };
22
+
23
+ const groupById = entities =>
24
+ entities.reduce(
25
+ (lookupMap, entity) => Object.assign({}, lookupMap, { [entity.id.uuid]: entity }),
26
+ {}
27
+ );
28
+
29
+ const formatMoney = money => {
30
+ // Be careful!!
31
+ //
32
+ // The division by hundred enters to the world of floating-points.
33
+ // In production software, it's recommended to use a library like decimal.js to handle money calculations
34
+ //
35
+ // See more: https://github.com/MikeMcl/decimal.js/
36
+ //
37
+ const majorUnitAmount = money.amount / 100;
38
+
39
+ return `${majorUnitAmount} ${money.currency}`;
40
+ };
41
+
42
+ //
43
+ // Rendering functions
44
+ //
45
+
46
+ const mainDiv = document.querySelector('.main');
47
+
48
+ const renderStatus = response => {
49
+ const statusTemplate = document.querySelector('.status');
50
+ const elem = statusTemplate.content.cloneNode(true);
51
+
52
+ elem.querySelector('.status-status').textContent = `${response.status} ${response.statusText}`;
53
+
54
+ mainDiv.appendChild(elem);
55
+ };
56
+
57
+ const renderMeta = response => {
58
+ const metaTemplate = document.querySelector('.meta');
59
+ const elem = metaTemplate.content.cloneNode(true);
60
+ const { meta } = response.data;
61
+
62
+ elem.querySelector('.meta-total-items').textContent = meta.totalItems;
63
+ elem.querySelector('.meta-page').textContent = `${meta.page} / ${meta.totalPages}`;
64
+ elem.querySelector('.meta-per-page').textContent = meta.perPage;
65
+
66
+ mainDiv.appendChild(elem);
67
+ };
68
+
69
+ const renderData = response => {
70
+ // Group images by ID for easy and fast lookup
71
+ const { included } = response.data;
72
+ const images = included ? groupById(included.filter(entity => entity.type === 'image')) : {};
73
+
74
+ const listingsTemplate = document.querySelector('.listings');
75
+ const listingsContainerElem = listingsTemplate.content.cloneNode(true);
76
+
77
+ const listingTemplate = document.querySelector('.listing');
78
+
79
+ response.data.data.forEach(listing => {
80
+ const elem = listingTemplate.content.cloneNode(true);
81
+
82
+ elem.querySelector('.listing-title').textContent = `${
83
+ listing.attributes.title
84
+ }, ${formatMoney(listing.attributes.price)}`;
85
+ elem.querySelector('.listing-id').textContent = listing.id.uuid;
86
+ elem.querySelector('.listing-geolocation').textContent = listing.attributes.geolocation
87
+ ? `${listing.attributes.geolocation.lat},${listing.attributes.geolocation.lng}`
88
+ : 'No location';
89
+ elem.querySelector('.listing-created-at').textContent = listing.attributes.createdAt;
90
+ elem.querySelector('.listing-state').textContent = listing.attributes.state;
91
+
92
+ const imagesElem = elem.querySelector('.listing-images');
93
+
94
+ listing.relationships.images.data.forEach(img => {
95
+ const image = images[img.id.uuid];
96
+ const listingImageElem = document.createElement('img');
97
+ listingImageElem.src = image.attributes.variants.default.url;
98
+ imagesElem.appendChild(listingImageElem);
99
+ });
100
+
101
+ listingsContainerElem.querySelector('.listings-listings').appendChild(elem);
102
+ });
103
+
104
+ mainDiv.appendChild(listingsContainerElem);
105
+ };
106
+
107
+ const renderForm = () => {
108
+ const formTemplate = document.querySelector('.form');
109
+ const elem = formTemplate.content.cloneNode(true);
110
+ mainDiv.appendChild(elem);
111
+ };
112
+
113
+ //
114
+ // Do the request
115
+ //
116
+
117
+ const doRequest = clientId => {
118
+ // Create new SDK instance using the given clientId
119
+ const sdk = sharetribeSdk.createInstance({
120
+ clientId,
121
+ });
122
+
123
+ // Call method sdk.listings.query with params include=images and
124
+ // per_page=5
125
+ //
126
+ // This will call the following API endpoint:
127
+ //
128
+ // /listings/query?include=images&per_page=5
129
+ //
130
+ // Returns a Promise.
131
+ //
132
+ sdk.listings
133
+ .query({ include: 'images', per_page: 5 })
134
+ .then(response => {
135
+ // Successful response
136
+ //
137
+ // Render the response
138
+ //
139
+ renderStatus(response);
140
+ renderMeta(response);
141
+ renderData(response);
142
+ })
143
+ .catch(response => {
144
+ // An error occurred
145
+ renderStatus(response);
146
+ });
147
+ };
148
+
149
+ const params = parseParams(window.location.search);
150
+
151
+ if (params.client_id) {
152
+ doRequest(params.client_id);
153
+ } else {
154
+ renderForm();
155
+ }
156
+ })();
@@ -0,0 +1,23 @@
1
+ # Getting started example (Node.js)
2
+
3
+ This example shows how to query listings using the SDK, in Node.js environment.
4
+
5
+ ## Requirements
6
+
7
+ * Node.js
8
+ * Yarn
9
+ * Client ID
10
+
11
+ ## How to run the example:
12
+
13
+ ```
14
+ $ cd [project-root]
15
+ $ yarn install
16
+ $ yarn run build
17
+ $ cd examples/getting-started-node
18
+ $ node index.js [clientId]
19
+ ```
20
+
21
+ ## Screenshots
22
+
23
+ ![Screenshot](screenshots/screenshot.png)
@@ -0,0 +1,139 @@
1
+ /* eslint-env node */
2
+
3
+ const sharetribeSdk = require('../../build/sharetribe-flex-sdk-node');
4
+
5
+ //
6
+ // Printing helpers
7
+ //
8
+
9
+ /* eslint no-console: "off" */
10
+ const cyan = msg => {
11
+ console.log('\x1b[36m%s\x1b[0m', msg);
12
+ };
13
+ const yellow = msg => {
14
+ console.log('\x1b[33m%s\x1b[0m', msg);
15
+ };
16
+ const normal = msg => {
17
+ console.log(msg);
18
+ };
19
+ const lineBreak = () => {
20
+ console.log();
21
+ };
22
+
23
+ const clientId = process.argv[2];
24
+
25
+ //
26
+ // Ensure clientId is set
27
+ //
28
+
29
+ if (!clientId) {
30
+ lineBreak();
31
+ cyan('Could not found clientId!');
32
+ lineBreak();
33
+ yellow('Usage: node index.js [clientId]');
34
+ lineBreak();
35
+ process.exit(1);
36
+ }
37
+
38
+ const formatMoney = money => {
39
+ // Be careful!!
40
+ //
41
+ // The division by hundred enters to the world of floating-points.
42
+ // In production software, it's recommended to use a library like decimal.js to handle money calculations
43
+ //
44
+ // See more: https://github.com/MikeMcl/decimal.js/
45
+ //
46
+ const majorUnitAmount = money.amount / 100;
47
+
48
+ return `${majorUnitAmount} ${money.currency}`;
49
+ };
50
+
51
+ const groupById = entities =>
52
+ entities.reduce(
53
+ (lookupMap, entity) => Object.assign({}, lookupMap, { [entity.id.uuid]: entity }),
54
+ {}
55
+ );
56
+
57
+ //
58
+ // Printing functions
59
+ //
60
+
61
+ const printStatus = response => {
62
+ lineBreak();
63
+ cyan(`** Response status:`);
64
+ lineBreak();
65
+ yellow(`${response.status} ${response.statusText}`);
66
+ lineBreak();
67
+ };
68
+
69
+ const printMeta = response => {
70
+ cyan('** Response meta:');
71
+ lineBreak();
72
+ yellow(`Total items: ${response.data.meta.totalItems}`);
73
+ yellow(`Page: ${response.data.meta.page} / ${response.data.meta.totalPages}`);
74
+ yellow(`Items per page: ${response.data.meta.perPage}`);
75
+ lineBreak();
76
+ };
77
+
78
+ const printData = response => {
79
+ // Group images by ID for easy and fast lookup
80
+ const { included } = response.data;
81
+ const images = included ? groupById(included.filter(entity => entity.type === 'image')) : {};
82
+
83
+ cyan('** Response data:');
84
+ lineBreak();
85
+ response.data.data.forEach(listing => {
86
+ yellow(`${listing.attributes.title}, ${formatMoney(listing.attributes.price)}`);
87
+ lineBreak();
88
+ normal(`ID: ${listing.id.uuid}`);
89
+ lineBreak();
90
+ normal(`Images:`);
91
+ listing.relationships.images.data.forEach(img => {
92
+ const image = images[img.id.uuid];
93
+ normal(`- ${image.attributes.variants.default.url}`);
94
+ });
95
+ lineBreak();
96
+ normal(
97
+ `Geolocation: ${listing.attributes.geolocation.lat},${listing.attributes.geolocation.lng}`
98
+ );
99
+ normal(`Created at: ${listing.attributes.createdAt}`);
100
+ normal(`State: ${listing.attributes.state}`);
101
+ lineBreak();
102
+ lineBreak();
103
+ });
104
+ };
105
+
106
+ // Create new SDK instance with clientId
107
+ const sdk = sharetribeSdk.createInstance({
108
+ clientId,
109
+ });
110
+
111
+ lineBreak();
112
+ cyan('** Request:');
113
+ lineBreak();
114
+ yellow(`clientId: ${clientId}`);
115
+
116
+ // Call method sdk.listings.query with params include=images and
117
+ // per_page=5
118
+ //
119
+ // This will call the following API endpoint:
120
+ //
121
+ // /listings/query?include=images&per_page=5
122
+ //
123
+ // Returns a Promise.
124
+ //
125
+ sdk.listings
126
+ .query({ include: 'images', per_page: 5 })
127
+ .then(response => {
128
+ // Successful response
129
+ //
130
+ // Render the response
131
+ //
132
+ printStatus(response);
133
+ printMeta(response);
134
+ printData(response);
135
+ })
136
+ .catch(response => {
137
+ // An error occurred
138
+ printStatus(response);
139
+ });
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "sharetribe-flex-sdk",
3
+ "version": "1.14.0",
4
+ "description": "Sharetribe Flex SDK for JavaScript",
5
+ "main": "build/sharetribe-flex-sdk-node.js",
6
+ "browser": "build/sharetribe-flex-sdk-web.js",
7
+ "scripts": {
8
+ "build": "webpack",
9
+ "lint": "eslint .",
10
+ "test": "jest",
11
+ "playground": "babel-node playground.js",
12
+ "pg": "babel-node playground.js",
13
+ "format": "prettier --write --print-width 100 --single-quote --trailing-comma es5 'src/**/*.js' 'examples/**/*.js'",
14
+ "serve-docs": "docpress serve",
15
+ "build-docs": "docpress build"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/sharetribe/flex-sdk-js.git"
20
+ },
21
+ "keywords": [
22
+ "sharetribe",
23
+ "api",
24
+ "sdk"
25
+ ],
26
+ "author": "Sharetribe",
27
+ "license": "Apache-2.0",
28
+ "bugs": {
29
+ "url": "https://github.com/sharetribe/flex-sdk-js/issues"
30
+ },
31
+ "homepage": "https://github.com/sharetribe/flex-sdk-js",
32
+ "devDependencies": {
33
+ "@babel/cli": "^7.0.0",
34
+ "@babel/core": "^7.0.0",
35
+ "@babel/node": "^7.0.0",
36
+ "@babel/plugin-proposal-class-properties": "^7.0.0",
37
+ "@babel/plugin-proposal-json-strings": "^7.0.0",
38
+ "@babel/plugin-syntax-dynamic-import": "^7.0.0",
39
+ "@babel/plugin-syntax-import-meta": "^7.0.0",
40
+ "@babel/preset-env": "^7.0.0",
41
+ "babel-core": "^7.0.0-bridge.0",
42
+ "babel-jest": "^23.4.2",
43
+ "babel-loader": "^8.0.0",
44
+ "babel-plugin-lodash": "^3.3.4",
45
+ "colors": "^1.3.1",
46
+ "command-line-args": "^5.1.1",
47
+ "command-line-usage": "^6.0.1",
48
+ "open": "^7.0.2",
49
+ "docpress": "^0.7.6",
50
+ "eslint": "^5.3.0",
51
+ "eslint-config-airbnb-base": "^13.0.0",
52
+ "eslint-config-prettier": "^2.9.0",
53
+ "eslint-plugin-import": "^2.13.0",
54
+ "eslint-plugin-jest": "^21.18.0",
55
+ "jest": "^24.8.0",
56
+ "prettier": "^1.14.0",
57
+ "webpack": "^3.12.0"
58
+ },
59
+ "dependencies": {
60
+ "axios": "^0.21.1",
61
+ "js-cookie": "^2.1.3",
62
+ "lodash": "^4.17.10",
63
+ "transit-js": "^0.8.861"
64
+ },
65
+ "resolutions": {
66
+ "docpress/**/lodash": "^4.17.10"
67
+ },
68
+ "babel": {
69
+ "plugins": [
70
+ "lodash",
71
+ "@babel/plugin-syntax-dynamic-import",
72
+ "@babel/plugin-syntax-import-meta",
73
+ "@babel/plugin-proposal-class-properties",
74
+ "@babel/plugin-proposal-json-strings"
75
+ ],
76
+ "presets": [
77
+ "@babel/preset-env"
78
+ ]
79
+ },
80
+ "jest": {
81
+ "testEnvironment": "node"
82
+ }
83
+ }