@atlaskit/editor-synced-block-provider 2.12.2 → 2.12.3
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 +8 -0
- package/dist/cjs/clients/block-service/blockService.js +6 -5
- package/dist/cjs/clients/confluence/contentProperty.js +4 -3
- package/dist/cjs/clients/confluence/sourceInfo.js +2 -1
- package/dist/cjs/common/types.js +5 -0
- package/dist/cjs/providers/block-service/blockServiceAPI.js +11 -0
- package/dist/cjs/utils/resolveSyncBlockInstance.js +3 -3
- package/dist/cjs/utils/retry.js +66 -0
- package/dist/es2019/clients/block-service/blockService.js +6 -5
- package/dist/es2019/clients/confluence/contentProperty.js +4 -3
- package/dist/es2019/clients/confluence/sourceInfo.js +2 -1
- package/dist/es2019/common/types.js +5 -0
- package/dist/es2019/providers/block-service/blockServiceAPI.js +11 -0
- package/dist/es2019/utils/resolveSyncBlockInstance.js +3 -3
- package/dist/es2019/utils/retry.js +26 -0
- package/dist/esm/clients/block-service/blockService.js +6 -5
- package/dist/esm/clients/confluence/contentProperty.js +4 -3
- package/dist/esm/clients/confluence/sourceInfo.js +2 -1
- package/dist/esm/common/types.js +5 -0
- package/dist/esm/providers/block-service/blockServiceAPI.js +11 -0
- package/dist/esm/utils/resolveSyncBlockInstance.js +3 -3
- package/dist/esm/utils/retry.js +60 -0
- package/dist/types/common/types.d.ts +4 -0
- package/dist/types/utils/retry.d.ts +1 -0
- package/dist/types-ts4.5/common/types.d.ts +4 -0
- package/dist/types-ts4.5/utils/retry.d.ts +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-synced-block-provider
|
|
2
2
|
|
|
3
|
+
## 2.12.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`707c3960baedb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/707c3960baedb) -
|
|
8
|
+
EDITOR-1923 retry api requests on rate limited for sync block provider
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 2.12.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -13,6 +13,7 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
|
|
|
13
13
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
14
14
|
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
|
|
15
15
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
16
|
+
var _retry = require("../../utils/retry");
|
|
16
17
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
17
18
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
18
19
|
var isBlockContentResponse = exports.isBlockContentResponse = function isBlockContentResponse(response) {
|
|
@@ -69,7 +70,7 @@ var getReferenceSyncedBlocks = exports.getReferenceSyncedBlocks = /*#__PURE__*/f
|
|
|
69
70
|
while (1) switch (_context.prev = _context.next) {
|
|
70
71
|
case 0:
|
|
71
72
|
_context.next = 2;
|
|
72
|
-
return
|
|
73
|
+
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block/document/reference/").concat(encodeURIComponent(documentAri)), {
|
|
73
74
|
method: 'GET',
|
|
74
75
|
headers: COMMON_HEADERS
|
|
75
76
|
});
|
|
@@ -119,7 +120,7 @@ var getSyncedBlockContent = exports.getSyncedBlockContent = /*#__PURE__*/functio
|
|
|
119
120
|
case 0:
|
|
120
121
|
blockAri = _ref2.blockAri;
|
|
121
122
|
_context2.next = 3;
|
|
122
|
-
return
|
|
123
|
+
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
123
124
|
method: 'GET',
|
|
124
125
|
headers: COMMON_HEADERS
|
|
125
126
|
});
|
|
@@ -153,7 +154,7 @@ var deleteSyncedBlock = exports.deleteSyncedBlock = /*#__PURE__*/function () {
|
|
|
153
154
|
case 0:
|
|
154
155
|
blockAri = _ref4.blockAri;
|
|
155
156
|
_context3.next = 3;
|
|
156
|
-
return
|
|
157
|
+
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
157
158
|
method: 'DELETE',
|
|
158
159
|
headers: COMMON_HEADERS
|
|
159
160
|
});
|
|
@@ -182,7 +183,7 @@ var updateSyncedBlock = exports.updateSyncedBlock = /*#__PURE__*/function () {
|
|
|
182
183
|
case 0:
|
|
183
184
|
blockAri = _ref6.blockAri, content = _ref6.content;
|
|
184
185
|
_context4.next = 3;
|
|
185
|
-
return
|
|
186
|
+
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
186
187
|
method: 'PUT',
|
|
187
188
|
headers: COMMON_HEADERS,
|
|
188
189
|
body: JSON.stringify({
|
|
@@ -214,7 +215,7 @@ var createSyncedBlock = exports.createSyncedBlock = /*#__PURE__*/function () {
|
|
|
214
215
|
case 0:
|
|
215
216
|
blockAri = _ref8.blockAri, blockInstanceId = _ref8.blockInstanceId, sourceAri = _ref8.sourceAri, product = _ref8.product, content = _ref8.content;
|
|
216
217
|
_context5.next = 3;
|
|
217
|
-
return
|
|
218
|
+
return (0, _retry.fetchWithRetry)("".concat(BLOCK_SERVICE_API_URL, "/block"), {
|
|
218
219
|
method: 'POST',
|
|
219
220
|
headers: COMMON_HEADERS,
|
|
220
221
|
body: JSON.stringify({
|
|
@@ -8,6 +8,7 @@ exports.updateContentProperty = exports.getContentProperty = exports.deleteConte
|
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
9
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
10
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
|
+
var _retry = require("../../utils/retry");
|
|
11
12
|
var _ari = require("./ari");
|
|
12
13
|
var _utils = require("./utils");
|
|
13
14
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -95,7 +96,7 @@ var getContentProperty = exports.getContentProperty = /*#__PURE__*/function () {
|
|
|
95
96
|
}
|
|
96
97
|
};
|
|
97
98
|
_context.next = 6;
|
|
98
|
-
return
|
|
99
|
+
return (0, _retry.fetchWithRetry)(GRAPHQL_ENDPOINT, {
|
|
99
100
|
method: 'POST',
|
|
100
101
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
101
102
|
body: JSON.stringify(bodyData)
|
|
@@ -204,7 +205,7 @@ var createContentProperty = exports.createContentProperty = /*#__PURE__*/functio
|
|
|
204
205
|
}
|
|
205
206
|
};
|
|
206
207
|
_context3.next = 6;
|
|
207
|
-
return
|
|
208
|
+
return (0, _retry.fetchWithRetry)(GRAPHQL_ENDPOINT, {
|
|
208
209
|
method: 'POST',
|
|
209
210
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
210
211
|
body: JSON.stringify(bodyData)
|
|
@@ -254,7 +255,7 @@ var deleteContentProperty = exports.deleteContentProperty = /*#__PURE__*/functio
|
|
|
254
255
|
}
|
|
255
256
|
};
|
|
256
257
|
_context4.next = 6;
|
|
257
|
-
return
|
|
258
|
+
return (0, _retry.fetchWithRetry)(GRAPHQL_ENDPOINT, {
|
|
258
259
|
method: 'POST',
|
|
259
260
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
260
261
|
body: JSON.stringify(bodyData)
|
|
@@ -10,6 +10,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
|
10
10
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
11
|
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
12
12
|
var _errorHandling = require("../../utils/errorHandling");
|
|
13
|
+
var _retry = require("../../utils/retry");
|
|
13
14
|
var _ari = require("./ari");
|
|
14
15
|
var _utils = require("./utils");
|
|
15
16
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -43,7 +44,7 @@ var getConfluenceSourceInfo = /*#__PURE__*/function () {
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
_context.next = 3;
|
|
46
|
-
return
|
|
47
|
+
return (0, _retry.fetchWithRetry)(GRAPHQL_ENDPOINT, {
|
|
47
48
|
method: 'POST',
|
|
48
49
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
49
50
|
body: JSON.stringify(bodyData)
|
package/dist/cjs/common/types.js
CHANGED
|
@@ -8,6 +8,11 @@ var SyncBlockError = exports.SyncBlockError = /*#__PURE__*/function (SyncBlockEr
|
|
|
8
8
|
SyncBlockError["Errored"] = "errored";
|
|
9
9
|
SyncBlockError["NotFound"] = "not_found";
|
|
10
10
|
SyncBlockError["Forbidden"] = "forbidden";
|
|
11
|
+
SyncBlockError["InvalidRequest"] = "invalid_request";
|
|
12
|
+
SyncBlockError["RateLimited"] = "rate_limited";
|
|
13
|
+
SyncBlockError["Conflict"] = "conflict";
|
|
14
|
+
// attempt to create block that already exists
|
|
15
|
+
SyncBlockError["ServerError"] = "server_error";
|
|
11
16
|
SyncBlockError["InvalidContent"] = "invalid_content"; // content is not a valid JSON
|
|
12
17
|
return SyncBlockError;
|
|
13
18
|
}({});
|
|
@@ -17,10 +17,21 @@ var _types = require("../../common/types");
|
|
|
17
17
|
var _errorHandling = require("../../utils/errorHandling");
|
|
18
18
|
var mapBlockError = function mapBlockError(error) {
|
|
19
19
|
switch (error.status) {
|
|
20
|
+
case 400:
|
|
21
|
+
case 401:
|
|
22
|
+
return _types.SyncBlockError.InvalidRequest;
|
|
20
23
|
case 403:
|
|
21
24
|
return _types.SyncBlockError.Forbidden;
|
|
22
25
|
case 404:
|
|
23
26
|
return _types.SyncBlockError.NotFound;
|
|
27
|
+
case 409:
|
|
28
|
+
return _types.SyncBlockError.Conflict;
|
|
29
|
+
case 429:
|
|
30
|
+
return _types.SyncBlockError.RateLimited;
|
|
31
|
+
case 500:
|
|
32
|
+
case 503:
|
|
33
|
+
case 504:
|
|
34
|
+
return _types.SyncBlockError.ServerError;
|
|
24
35
|
}
|
|
25
36
|
return _types.SyncBlockError.Errored;
|
|
26
37
|
};
|
|
@@ -26,10 +26,10 @@ var resolveSyncBlockInstance = exports.resolveSyncBlockInstance = function resol
|
|
|
26
26
|
return newResult;
|
|
27
27
|
} else if (!newResult.data) {
|
|
28
28
|
// return the old result if there was an error, e.g. network error, but not if not found or forbidden
|
|
29
|
-
if (newResult.error === _types.SyncBlockError.
|
|
30
|
-
return oldResult;
|
|
31
|
-
} else {
|
|
29
|
+
if (newResult.error === _types.SyncBlockError.NotFound || newResult.error === _types.SyncBlockError.Forbidden) {
|
|
32
30
|
return newResult;
|
|
31
|
+
} else {
|
|
32
|
+
return oldResult;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.fetchWithRetry = void 0;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
10
|
+
var parseRetryAfter = function parseRetryAfter(retryAfter) {
|
|
11
|
+
var newDelay;
|
|
12
|
+
|
|
13
|
+
// retryAfter can either be in ms or HTTP date
|
|
14
|
+
var parsedRetryAfter = parseInt(retryAfter);
|
|
15
|
+
if (!isNaN(parsedRetryAfter)) {
|
|
16
|
+
newDelay = parsedRetryAfter * 1000;
|
|
17
|
+
} else {
|
|
18
|
+
var retryDate = new Date(retryAfter);
|
|
19
|
+
var delayFromDate = retryDate.getTime() - Date.now();
|
|
20
|
+
if (delayFromDate > 0) {
|
|
21
|
+
newDelay = delayFromDate;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return newDelay;
|
|
25
|
+
};
|
|
26
|
+
var _fetchWithRetry = exports.fetchWithRetry = /*#__PURE__*/function () {
|
|
27
|
+
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(url, options) {
|
|
28
|
+
var retriesRemaining,
|
|
29
|
+
delay,
|
|
30
|
+
response,
|
|
31
|
+
shouldRetry,
|
|
32
|
+
retryAfter,
|
|
33
|
+
_args = arguments;
|
|
34
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
35
|
+
while (1) switch (_context.prev = _context.next) {
|
|
36
|
+
case 0:
|
|
37
|
+
retriesRemaining = _args.length > 2 && _args[2] !== undefined ? _args[2] : 3;
|
|
38
|
+
delay = _args.length > 3 && _args[3] !== undefined ? _args[3] : 1000;
|
|
39
|
+
_context.next = 4;
|
|
40
|
+
return fetch(url, options);
|
|
41
|
+
case 4:
|
|
42
|
+
response = _context.sent;
|
|
43
|
+
shouldRetry = !response.ok && response.status === 429 && retriesRemaining > 1;
|
|
44
|
+
if (shouldRetry) {
|
|
45
|
+
_context.next = 8;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
return _context.abrupt("return", response);
|
|
49
|
+
case 8:
|
|
50
|
+
retryAfter = response.headers.get('Retry-After');
|
|
51
|
+
_context.next = 11;
|
|
52
|
+
return new Promise(function (resolve) {
|
|
53
|
+
return setTimeout(resolve, retryAfter ? parseRetryAfter(retryAfter) : delay);
|
|
54
|
+
});
|
|
55
|
+
case 11:
|
|
56
|
+
return _context.abrupt("return", _fetchWithRetry(url, options, retriesRemaining - 1, delay * 2));
|
|
57
|
+
case 12:
|
|
58
|
+
case "end":
|
|
59
|
+
return _context.stop();
|
|
60
|
+
}
|
|
61
|
+
}, _callee);
|
|
62
|
+
}));
|
|
63
|
+
return function fetchWithRetry(_x, _x2) {
|
|
64
|
+
return _ref.apply(this, arguments);
|
|
65
|
+
};
|
|
66
|
+
}();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
1
2
|
export const isBlockContentResponse = response => {
|
|
2
3
|
const content = response.content;
|
|
3
4
|
return typeof content === 'string';
|
|
@@ -46,7 +47,7 @@ export const isBlockContentResponse = response => {
|
|
|
46
47
|
* Check https://block-service.dev.atl-paas.net/ for latest API documentation.
|
|
47
48
|
*/
|
|
48
49
|
export const getReferenceSyncedBlocks = async documentAri => {
|
|
49
|
-
const response = await
|
|
50
|
+
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block/document/reference/${encodeURIComponent(documentAri)}`, {
|
|
50
51
|
method: 'GET',
|
|
51
52
|
headers: COMMON_HEADERS
|
|
52
53
|
});
|
|
@@ -69,7 +70,7 @@ export class BlockError extends Error {
|
|
|
69
70
|
export const getSyncedBlockContent = async ({
|
|
70
71
|
blockAri
|
|
71
72
|
}) => {
|
|
72
|
-
const response = await
|
|
73
|
+
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
73
74
|
method: 'GET',
|
|
74
75
|
headers: COMMON_HEADERS
|
|
75
76
|
});
|
|
@@ -81,7 +82,7 @@ export const getSyncedBlockContent = async ({
|
|
|
81
82
|
export const deleteSyncedBlock = async ({
|
|
82
83
|
blockAri
|
|
83
84
|
}) => {
|
|
84
|
-
const response = await
|
|
85
|
+
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
85
86
|
method: 'DELETE',
|
|
86
87
|
headers: COMMON_HEADERS
|
|
87
88
|
});
|
|
@@ -93,7 +94,7 @@ export const updateSyncedBlock = async ({
|
|
|
93
94
|
blockAri,
|
|
94
95
|
content
|
|
95
96
|
}) => {
|
|
96
|
-
const response = await
|
|
97
|
+
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block/${encodeURIComponent(blockAri)}`, {
|
|
97
98
|
method: 'PUT',
|
|
98
99
|
headers: COMMON_HEADERS,
|
|
99
100
|
body: JSON.stringify({
|
|
@@ -111,7 +112,7 @@ export const createSyncedBlock = async ({
|
|
|
111
112
|
product,
|
|
112
113
|
content
|
|
113
114
|
}) => {
|
|
114
|
-
const response = await
|
|
115
|
+
const response = await fetchWithRetry(`${BLOCK_SERVICE_API_URL}/block`, {
|
|
115
116
|
method: 'POST',
|
|
116
117
|
headers: COMMON_HEADERS,
|
|
117
118
|
body: JSON.stringify({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
1
2
|
import { getConfluencePageAri } from './ari';
|
|
2
3
|
import { isBlogPageType } from './utils';
|
|
3
4
|
const COMMON_HEADERS = {
|
|
@@ -151,7 +152,7 @@ export const getContentProperty = async ({
|
|
|
151
152
|
keys: [key]
|
|
152
153
|
}
|
|
153
154
|
};
|
|
154
|
-
const response = await
|
|
155
|
+
const response = await fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
155
156
|
method: 'POST',
|
|
156
157
|
headers: {
|
|
157
158
|
...COMMON_HEADERS,
|
|
@@ -237,7 +238,7 @@ export const createContentProperty = async ({
|
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
240
|
};
|
|
240
|
-
const response = await
|
|
241
|
+
const response = await fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
241
242
|
method: 'POST',
|
|
242
243
|
headers: {
|
|
243
244
|
...COMMON_HEADERS,
|
|
@@ -272,7 +273,7 @@ export const deleteContentProperty = async ({
|
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
};
|
|
275
|
-
const response = await
|
|
276
|
+
const response = await fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
276
277
|
method: 'POST',
|
|
277
278
|
headers: {
|
|
278
279
|
...COMMON_HEADERS,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
4
4
|
import { getSourceInfoErrorPayload } from '../../utils/errorHandling';
|
|
5
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
5
6
|
import { getPageIdAndTypeFromConfluencePageAri } from './ari';
|
|
6
7
|
import { isBlogPageType } from './utils';
|
|
7
8
|
const COMMON_HEADERS = {
|
|
@@ -41,7 +42,7 @@ const getConfluenceSourceInfo = async ari => {
|
|
|
41
42
|
id: ari
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
|
-
const response = await
|
|
45
|
+
const response = await fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
45
46
|
method: 'POST',
|
|
46
47
|
headers: {
|
|
47
48
|
...COMMON_HEADERS,
|
|
@@ -2,6 +2,11 @@ export let SyncBlockError = /*#__PURE__*/function (SyncBlockError) {
|
|
|
2
2
|
SyncBlockError["Errored"] = "errored";
|
|
3
3
|
SyncBlockError["NotFound"] = "not_found";
|
|
4
4
|
SyncBlockError["Forbidden"] = "forbidden";
|
|
5
|
+
SyncBlockError["InvalidRequest"] = "invalid_request";
|
|
6
|
+
SyncBlockError["RateLimited"] = "rate_limited";
|
|
7
|
+
SyncBlockError["Conflict"] = "conflict";
|
|
8
|
+
// attempt to create block that already exists
|
|
9
|
+
SyncBlockError["ServerError"] = "server_error";
|
|
5
10
|
SyncBlockError["InvalidContent"] = "invalid_content"; // content is not a valid JSON
|
|
6
11
|
return SyncBlockError;
|
|
7
12
|
}({});
|
|
@@ -5,10 +5,21 @@ import { SyncBlockError } from '../../common/types';
|
|
|
5
5
|
import { stringifyError } from '../../utils/errorHandling';
|
|
6
6
|
const mapBlockError = error => {
|
|
7
7
|
switch (error.status) {
|
|
8
|
+
case 400:
|
|
9
|
+
case 401:
|
|
10
|
+
return SyncBlockError.InvalidRequest;
|
|
8
11
|
case 403:
|
|
9
12
|
return SyncBlockError.Forbidden;
|
|
10
13
|
case 404:
|
|
11
14
|
return SyncBlockError.NotFound;
|
|
15
|
+
case 409:
|
|
16
|
+
return SyncBlockError.Conflict;
|
|
17
|
+
case 429:
|
|
18
|
+
return SyncBlockError.RateLimited;
|
|
19
|
+
case 500:
|
|
20
|
+
case 503:
|
|
21
|
+
case 504:
|
|
22
|
+
return SyncBlockError.ServerError;
|
|
12
23
|
}
|
|
13
24
|
return SyncBlockError.Errored;
|
|
14
25
|
};
|
|
@@ -16,10 +16,10 @@ export const resolveSyncBlockInstance = (oldResult, newResult) => {
|
|
|
16
16
|
return newResult;
|
|
17
17
|
} else if (!newResult.data) {
|
|
18
18
|
// return the old result if there was an error, e.g. network error, but not if not found or forbidden
|
|
19
|
-
if (newResult.error === SyncBlockError.
|
|
20
|
-
return oldResult;
|
|
21
|
-
} else {
|
|
19
|
+
if (newResult.error === SyncBlockError.NotFound || newResult.error === SyncBlockError.Forbidden) {
|
|
22
20
|
return newResult;
|
|
21
|
+
} else {
|
|
22
|
+
return oldResult;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const parseRetryAfter = retryAfter => {
|
|
2
|
+
let newDelay;
|
|
3
|
+
|
|
4
|
+
// retryAfter can either be in ms or HTTP date
|
|
5
|
+
const parsedRetryAfter = parseInt(retryAfter);
|
|
6
|
+
if (!isNaN(parsedRetryAfter)) {
|
|
7
|
+
newDelay = parsedRetryAfter * 1000;
|
|
8
|
+
} else {
|
|
9
|
+
const retryDate = new Date(retryAfter);
|
|
10
|
+
const delayFromDate = retryDate.getTime() - Date.now();
|
|
11
|
+
if (delayFromDate > 0) {
|
|
12
|
+
newDelay = delayFromDate;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return newDelay;
|
|
16
|
+
};
|
|
17
|
+
export const fetchWithRetry = async (url, options, retriesRemaining = 3, delay = 1000) => {
|
|
18
|
+
const response = await fetch(url, options);
|
|
19
|
+
const shouldRetry = !response.ok && response.status === 429 && retriesRemaining > 1;
|
|
20
|
+
if (!shouldRetry) {
|
|
21
|
+
return response;
|
|
22
|
+
}
|
|
23
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
24
|
+
await new Promise(resolve => setTimeout(resolve, retryAfter ? parseRetryAfter(retryAfter) : delay));
|
|
25
|
+
return fetchWithRetry(url, options, retriesRemaining - 1, delay * 2);
|
|
26
|
+
};
|
|
@@ -8,6 +8,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
|
8
8
|
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
9
9
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
10
10
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
11
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
11
12
|
export var isBlockContentResponse = function isBlockContentResponse(response) {
|
|
12
13
|
var content = response.content;
|
|
13
14
|
return typeof content === 'string';
|
|
@@ -62,7 +63,7 @@ export var getReferenceSyncedBlocks = /*#__PURE__*/function () {
|
|
|
62
63
|
while (1) switch (_context.prev = _context.next) {
|
|
63
64
|
case 0:
|
|
64
65
|
_context.next = 2;
|
|
65
|
-
return
|
|
66
|
+
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block/document/reference/").concat(encodeURIComponent(documentAri)), {
|
|
66
67
|
method: 'GET',
|
|
67
68
|
headers: COMMON_HEADERS
|
|
68
69
|
});
|
|
@@ -112,7 +113,7 @@ export var getSyncedBlockContent = /*#__PURE__*/function () {
|
|
|
112
113
|
case 0:
|
|
113
114
|
blockAri = _ref2.blockAri;
|
|
114
115
|
_context2.next = 3;
|
|
115
|
-
return
|
|
116
|
+
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
116
117
|
method: 'GET',
|
|
117
118
|
headers: COMMON_HEADERS
|
|
118
119
|
});
|
|
@@ -146,7 +147,7 @@ export var deleteSyncedBlock = /*#__PURE__*/function () {
|
|
|
146
147
|
case 0:
|
|
147
148
|
blockAri = _ref4.blockAri;
|
|
148
149
|
_context3.next = 3;
|
|
149
|
-
return
|
|
150
|
+
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
150
151
|
method: 'DELETE',
|
|
151
152
|
headers: COMMON_HEADERS
|
|
152
153
|
});
|
|
@@ -175,7 +176,7 @@ export var updateSyncedBlock = /*#__PURE__*/function () {
|
|
|
175
176
|
case 0:
|
|
176
177
|
blockAri = _ref6.blockAri, content = _ref6.content;
|
|
177
178
|
_context4.next = 3;
|
|
178
|
-
return
|
|
179
|
+
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block/").concat(encodeURIComponent(blockAri)), {
|
|
179
180
|
method: 'PUT',
|
|
180
181
|
headers: COMMON_HEADERS,
|
|
181
182
|
body: JSON.stringify({
|
|
@@ -207,7 +208,7 @@ export var createSyncedBlock = /*#__PURE__*/function () {
|
|
|
207
208
|
case 0:
|
|
208
209
|
blockAri = _ref8.blockAri, blockInstanceId = _ref8.blockInstanceId, sourceAri = _ref8.sourceAri, product = _ref8.product, content = _ref8.content;
|
|
209
210
|
_context5.next = 3;
|
|
210
|
-
return
|
|
211
|
+
return fetchWithRetry("".concat(BLOCK_SERVICE_API_URL, "/block"), {
|
|
211
212
|
method: 'POST',
|
|
212
213
|
headers: COMMON_HEADERS,
|
|
213
214
|
body: JSON.stringify({
|
|
@@ -3,6 +3,7 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
|
3
3
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
4
4
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
5
5
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
6
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
6
7
|
import { getConfluencePageAri } from './ari';
|
|
7
8
|
import { isBlogPageType } from './utils';
|
|
8
9
|
var COMMON_HEADERS = {
|
|
@@ -88,7 +89,7 @@ export var getContentProperty = /*#__PURE__*/function () {
|
|
|
88
89
|
}
|
|
89
90
|
};
|
|
90
91
|
_context.next = 6;
|
|
91
|
-
return
|
|
92
|
+
return fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
92
93
|
method: 'POST',
|
|
93
94
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
94
95
|
body: JSON.stringify(bodyData)
|
|
@@ -197,7 +198,7 @@ export var createContentProperty = /*#__PURE__*/function () {
|
|
|
197
198
|
}
|
|
198
199
|
};
|
|
199
200
|
_context3.next = 6;
|
|
200
|
-
return
|
|
201
|
+
return fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
201
202
|
method: 'POST',
|
|
202
203
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
203
204
|
body: JSON.stringify(bodyData)
|
|
@@ -247,7 +248,7 @@ export var deleteContentProperty = /*#__PURE__*/function () {
|
|
|
247
248
|
}
|
|
248
249
|
};
|
|
249
250
|
_context4.next = 6;
|
|
250
|
-
return
|
|
251
|
+
return fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
251
252
|
method: 'POST',
|
|
252
253
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
253
254
|
body: JSON.stringify(bodyData)
|
|
@@ -7,6 +7,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
7
7
|
|
|
8
8
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
9
9
|
import { getSourceInfoErrorPayload } from '../../utils/errorHandling';
|
|
10
|
+
import { fetchWithRetry } from '../../utils/retry';
|
|
10
11
|
import { getPageIdAndTypeFromConfluencePageAri } from './ari';
|
|
11
12
|
import { isBlogPageType } from './utils';
|
|
12
13
|
var COMMON_HEADERS = {
|
|
@@ -38,7 +39,7 @@ var getConfluenceSourceInfo = /*#__PURE__*/function () {
|
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
_context.next = 3;
|
|
41
|
-
return
|
|
42
|
+
return fetchWithRetry(GRAPHQL_ENDPOINT, {
|
|
42
43
|
method: 'POST',
|
|
43
44
|
headers: _objectSpread(_objectSpread({}, COMMON_HEADERS), AGG_HEADERS),
|
|
44
45
|
body: JSON.stringify(bodyData)
|
package/dist/esm/common/types.js
CHANGED
|
@@ -2,6 +2,11 @@ export var SyncBlockError = /*#__PURE__*/function (SyncBlockError) {
|
|
|
2
2
|
SyncBlockError["Errored"] = "errored";
|
|
3
3
|
SyncBlockError["NotFound"] = "not_found";
|
|
4
4
|
SyncBlockError["Forbidden"] = "forbidden";
|
|
5
|
+
SyncBlockError["InvalidRequest"] = "invalid_request";
|
|
6
|
+
SyncBlockError["RateLimited"] = "rate_limited";
|
|
7
|
+
SyncBlockError["Conflict"] = "conflict";
|
|
8
|
+
// attempt to create block that already exists
|
|
9
|
+
SyncBlockError["ServerError"] = "server_error";
|
|
5
10
|
SyncBlockError["InvalidContent"] = "invalid_content"; // content is not a valid JSON
|
|
6
11
|
return SyncBlockError;
|
|
7
12
|
}({});
|
|
@@ -10,10 +10,21 @@ import { SyncBlockError } from '../../common/types';
|
|
|
10
10
|
import { stringifyError } from '../../utils/errorHandling';
|
|
11
11
|
var mapBlockError = function mapBlockError(error) {
|
|
12
12
|
switch (error.status) {
|
|
13
|
+
case 400:
|
|
14
|
+
case 401:
|
|
15
|
+
return SyncBlockError.InvalidRequest;
|
|
13
16
|
case 403:
|
|
14
17
|
return SyncBlockError.Forbidden;
|
|
15
18
|
case 404:
|
|
16
19
|
return SyncBlockError.NotFound;
|
|
20
|
+
case 409:
|
|
21
|
+
return SyncBlockError.Conflict;
|
|
22
|
+
case 429:
|
|
23
|
+
return SyncBlockError.RateLimited;
|
|
24
|
+
case 500:
|
|
25
|
+
case 503:
|
|
26
|
+
case 504:
|
|
27
|
+
return SyncBlockError.ServerError;
|
|
17
28
|
}
|
|
18
29
|
return SyncBlockError.Errored;
|
|
19
30
|
};
|
|
@@ -19,10 +19,10 @@ export var resolveSyncBlockInstance = function resolveSyncBlockInstance(oldResul
|
|
|
19
19
|
return newResult;
|
|
20
20
|
} else if (!newResult.data) {
|
|
21
21
|
// return the old result if there was an error, e.g. network error, but not if not found or forbidden
|
|
22
|
-
if (newResult.error === SyncBlockError.
|
|
23
|
-
return oldResult;
|
|
24
|
-
} else {
|
|
22
|
+
if (newResult.error === SyncBlockError.NotFound || newResult.error === SyncBlockError.Forbidden) {
|
|
25
23
|
return newResult;
|
|
24
|
+
} else {
|
|
25
|
+
return oldResult;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
+
var parseRetryAfter = function parseRetryAfter(retryAfter) {
|
|
4
|
+
var newDelay;
|
|
5
|
+
|
|
6
|
+
// retryAfter can either be in ms or HTTP date
|
|
7
|
+
var parsedRetryAfter = parseInt(retryAfter);
|
|
8
|
+
if (!isNaN(parsedRetryAfter)) {
|
|
9
|
+
newDelay = parsedRetryAfter * 1000;
|
|
10
|
+
} else {
|
|
11
|
+
var retryDate = new Date(retryAfter);
|
|
12
|
+
var delayFromDate = retryDate.getTime() - Date.now();
|
|
13
|
+
if (delayFromDate > 0) {
|
|
14
|
+
newDelay = delayFromDate;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return newDelay;
|
|
18
|
+
};
|
|
19
|
+
var _fetchWithRetry = /*#__PURE__*/function () {
|
|
20
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url, options) {
|
|
21
|
+
var retriesRemaining,
|
|
22
|
+
delay,
|
|
23
|
+
response,
|
|
24
|
+
shouldRetry,
|
|
25
|
+
retryAfter,
|
|
26
|
+
_args = arguments;
|
|
27
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
28
|
+
while (1) switch (_context.prev = _context.next) {
|
|
29
|
+
case 0:
|
|
30
|
+
retriesRemaining = _args.length > 2 && _args[2] !== undefined ? _args[2] : 3;
|
|
31
|
+
delay = _args.length > 3 && _args[3] !== undefined ? _args[3] : 1000;
|
|
32
|
+
_context.next = 4;
|
|
33
|
+
return fetch(url, options);
|
|
34
|
+
case 4:
|
|
35
|
+
response = _context.sent;
|
|
36
|
+
shouldRetry = !response.ok && response.status === 429 && retriesRemaining > 1;
|
|
37
|
+
if (shouldRetry) {
|
|
38
|
+
_context.next = 8;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
return _context.abrupt("return", response);
|
|
42
|
+
case 8:
|
|
43
|
+
retryAfter = response.headers.get('Retry-After');
|
|
44
|
+
_context.next = 11;
|
|
45
|
+
return new Promise(function (resolve) {
|
|
46
|
+
return setTimeout(resolve, retryAfter ? parseRetryAfter(retryAfter) : delay);
|
|
47
|
+
});
|
|
48
|
+
case 11:
|
|
49
|
+
return _context.abrupt("return", _fetchWithRetry(url, options, retriesRemaining - 1, delay * 2));
|
|
50
|
+
case 12:
|
|
51
|
+
case "end":
|
|
52
|
+
return _context.stop();
|
|
53
|
+
}
|
|
54
|
+
}, _callee);
|
|
55
|
+
}));
|
|
56
|
+
return function fetchWithRetry(_x, _x2) {
|
|
57
|
+
return _ref.apply(this, arguments);
|
|
58
|
+
};
|
|
59
|
+
}();
|
|
60
|
+
export { _fetchWithRetry as fetchWithRetry };
|
|
@@ -16,6 +16,10 @@ export declare enum SyncBlockError {
|
|
|
16
16
|
Errored = "errored",
|
|
17
17
|
NotFound = "not_found",
|
|
18
18
|
Forbidden = "forbidden",
|
|
19
|
+
InvalidRequest = "invalid_request",
|
|
20
|
+
RateLimited = "rate_limited",
|
|
21
|
+
Conflict = "conflict",// attempt to create block that already exists
|
|
22
|
+
ServerError = "server_error",
|
|
19
23
|
InvalidContent = "invalid_content"
|
|
20
24
|
}
|
|
21
25
|
export interface SyncBlockData {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const fetchWithRetry: (url: string, options: RequestInit, retriesRemaining?: number, delay?: number) => Promise<Response>;
|
|
@@ -16,6 +16,10 @@ export declare enum SyncBlockError {
|
|
|
16
16
|
Errored = "errored",
|
|
17
17
|
NotFound = "not_found",
|
|
18
18
|
Forbidden = "forbidden",
|
|
19
|
+
InvalidRequest = "invalid_request",
|
|
20
|
+
RateLimited = "rate_limited",
|
|
21
|
+
Conflict = "conflict",// attempt to create block that already exists
|
|
22
|
+
ServerError = "server_error",
|
|
19
23
|
InvalidContent = "invalid_content"
|
|
20
24
|
}
|
|
21
25
|
export interface SyncBlockData {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const fetchWithRetry: (url: string, options: RequestInit, retriesRemaining?: number, delay?: number) => Promise<Response>;
|
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"uuid": "^3.1.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@atlaskit/editor-common": "^110.
|
|
37
|
+
"@atlaskit/editor-common": "^110.39.0",
|
|
38
38
|
"react": "^18.2.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
"name": "@atlaskit/editor-synced-block-provider",
|
|
80
|
-
"version": "2.12.
|
|
80
|
+
"version": "2.12.3",
|
|
81
81
|
"description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
|
|
82
82
|
"author": "Atlassian Pty Ltd",
|
|
83
83
|
"license": "Apache-2.0",
|