@atlaskit/editor-synced-block-provider 3.4.0 → 3.5.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/CHANGELOG.md +15 -0
- package/dist/cjs/providers/block-service/blockServiceAPI.js +40 -6
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +33 -6
- package/dist/es2019/providers/block-service/blockServiceAPI.js +39 -5
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +31 -6
- package/dist/esm/providers/block-service/blockServiceAPI.js +39 -5
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +33 -6
- package/dist/types/providers/block-service/blockServiceAPI.d.ts +19 -0
- package/dist/types/store-manager/sourceSyncBlockStoreManager.d.ts +3 -0
- package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +19 -0
- package/dist/types-ts4.5/store-manager/sourceSyncBlockStoreManager.d.ts +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/editor-synced-block-provider
|
|
2
2
|
|
|
3
|
+
## 3.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`25da5a5d67a2a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/25da5a5d67a2a) -
|
|
8
|
+
EDITOR-2257 implement resourceId conversion and enable SSR
|
|
9
|
+
|
|
10
|
+
## 3.4.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [`656adaeec9d0b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/656adaeec9d0b) -
|
|
15
|
+
[ux] EDITOR-1665 add experience tracking for create sync block
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
|
|
3
18
|
## 3.4.0
|
|
4
19
|
|
|
5
20
|
### Minor Changes
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.useMemoizedBlockServiceFetchOnlyAPIProvider = exports.useMemoizedBlockServiceAPIProviders = exports.fetchReferences = exports.createBlockServiceFetchOnlyAPIProvider = exports.createBlockServiceAPIProviders = void 0;
|
|
7
|
+
exports.useMemoizedBlockServiceFetchOnlyAPIProvider = exports.useMemoizedBlockServiceAPIProviders = exports.fetchReferences = exports.createBlockServiceFetchOnlyAPIProvider = exports.createBlockServiceAPIProviders = exports.convertToSyncBlockData = exports.blockAriToResourceId = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
9
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
10
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
@@ -39,6 +39,32 @@ var mapBlockError = function mapBlockError(error) {
|
|
|
39
39
|
return _types.SyncBlockError.Errored;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Extracts the ResourceId from a block ARI by returning the full path after synced-block/.
|
|
44
|
+
*
|
|
45
|
+
* Document ARI format from Block Service API:
|
|
46
|
+
* "ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}"
|
|
47
|
+
*
|
|
48
|
+
* ResourceId format (extracted from ARI):
|
|
49
|
+
* "{product}/{parentId}/{resourceId}" (the full path after synced-block/)
|
|
50
|
+
*
|
|
51
|
+
* Example in context:
|
|
52
|
+
* Input: "ari:cloud:blocks:{uuid}:synced-block/confluence-page/{pageId}/{resourceId}"
|
|
53
|
+
* Output: "confluence-page/{pageId}/{resourceId}"
|
|
54
|
+
*
|
|
55
|
+
* @param blockAri - The block ARI string from Block Service API
|
|
56
|
+
* @returns The ResourceId (full path after synced-block/)
|
|
57
|
+
*/
|
|
58
|
+
var blockAriToResourceId = exports.blockAriToResourceId = function blockAriToResourceId(blockAri) {
|
|
59
|
+
// Validate ARI format and extract resourceId using regex
|
|
60
|
+
// Format: ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}
|
|
61
|
+
// The regex captures the full path after synced-block/
|
|
62
|
+
// e.g. ari:cloud:blocks:DUMMY-a5a01d21-1cc3-4f29-9565-f2bb8cd969f5:synced-block/confluence-page/455232061495/e8cf64e3-1b6e-489b-ad86-8465b0905bb4
|
|
63
|
+
// should return confluence-page/455232061495/e8cf64e3-1b6e-489b-ad86-8465b0905bb4
|
|
64
|
+
var match = blockAri.match(/^ari:cloud:blocks:.*:synced-block\/(.+)$/);
|
|
65
|
+
return (match === null || match === void 0 ? void 0 : match[1]) || null;
|
|
66
|
+
};
|
|
67
|
+
|
|
42
68
|
// convert BlockContentResponse to SyncBlockData
|
|
43
69
|
// throws exception if JSON parsing fails
|
|
44
70
|
// what's missing from BlockContentResponse to SyncBlockData:
|
|
@@ -46,9 +72,9 @@ var mapBlockError = function mapBlockError(error) {
|
|
|
46
72
|
// - sourceURL
|
|
47
73
|
// - sourceTitle
|
|
48
74
|
// - isSynced
|
|
49
|
-
var convertToSyncBlockData = function convertToSyncBlockData(data) {
|
|
75
|
+
var convertToSyncBlockData = exports.convertToSyncBlockData = function convertToSyncBlockData(data, resourceId) {
|
|
50
76
|
var createdAt;
|
|
51
|
-
if (data.createdAt) {
|
|
77
|
+
if (data.createdAt !== undefined && data.createdAt !== null) {
|
|
52
78
|
try {
|
|
53
79
|
// BE returns microseconds, convert to milliseconds
|
|
54
80
|
// BE should fix this in the future
|
|
@@ -65,7 +91,7 @@ var convertToSyncBlockData = function convertToSyncBlockData(data) {
|
|
|
65
91
|
createdAt: createdAt,
|
|
66
92
|
createdBy: data.createdBy,
|
|
67
93
|
product: data.product,
|
|
68
|
-
resourceId:
|
|
94
|
+
resourceId: resourceId,
|
|
69
95
|
sourceAri: data.sourceAri
|
|
70
96
|
};
|
|
71
97
|
};
|
|
@@ -96,9 +122,17 @@ var fetchReferences = exports.fetchReferences = /*#__PURE__*/function () {
|
|
|
96
122
|
_ref2 = response || {}, blocks = _ref2.blocks, errors = _ref2.errors;
|
|
97
123
|
blocksInstances = (blocks || []).map(function (blockContentResponse) {
|
|
98
124
|
try {
|
|
125
|
+
var resourceId = blockAriToResourceId(blockContentResponse.blockAri);
|
|
126
|
+
if (!resourceId) {
|
|
127
|
+
// could not extract resourceId from blockAri, return InvalidContent error
|
|
128
|
+
return {
|
|
129
|
+
error: _types.SyncBlockError.InvalidContent,
|
|
130
|
+
resourceId: blockContentResponse.blockAri
|
|
131
|
+
};
|
|
132
|
+
}
|
|
99
133
|
return {
|
|
100
|
-
data: convertToSyncBlockData(blockContentResponse),
|
|
101
|
-
resourceId:
|
|
134
|
+
data: convertToSyncBlockData(blockContentResponse, resourceId),
|
|
135
|
+
resourceId: resourceId
|
|
102
136
|
};
|
|
103
137
|
} catch (_unused) {
|
|
104
138
|
// JSON parsing error, return InvalidContent error
|
|
@@ -11,6 +11,7 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
|
|
|
11
11
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
12
12
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
13
13
|
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
14
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
14
15
|
var _types = require("../common/types");
|
|
15
16
|
var _errorHandling = require("../utils/errorHandling");
|
|
16
17
|
var _utils = require("../utils/utils");
|
|
@@ -39,6 +40,11 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
39
40
|
value: function setFireAnalyticsEvent(fireAnalyticsEvent) {
|
|
40
41
|
this.fireAnalyticsEvent = fireAnalyticsEvent;
|
|
41
42
|
}
|
|
43
|
+
}, {
|
|
44
|
+
key: "setCreateExperience",
|
|
45
|
+
value: function setCreateExperience(createExperience) {
|
|
46
|
+
this.createExperience = createExperience;
|
|
47
|
+
}
|
|
42
48
|
}, {
|
|
43
49
|
key: "isSourceBlock",
|
|
44
50
|
value: function isSourceBlock(node) {
|
|
@@ -271,28 +277,49 @@ var SourceSyncBlockStoreManager = exports.SourceSyncBlockStoreManager = /*#__PUR
|
|
|
271
277
|
if (resourceId) {
|
|
272
278
|
_this4.commitPendingCreation(true);
|
|
273
279
|
} else {
|
|
274
|
-
var _this4$fireAnalyticsE;
|
|
275
280
|
_this4.commitPendingCreation(false);
|
|
276
|
-
|
|
281
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_dogfooding')) {
|
|
282
|
+
var _this4$createExperien;
|
|
283
|
+
(_this4$createExperien = _this4.createExperience) === null || _this4$createExperien === void 0 || _this4$createExperien.failure({
|
|
284
|
+
reason: result.error || 'Failed to create bodied sync block'
|
|
285
|
+
});
|
|
286
|
+
} else {
|
|
287
|
+
var _this4$fireAnalyticsE;
|
|
288
|
+
(_this4$fireAnalyticsE = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE === void 0 || _this4$fireAnalyticsE.call(_this4, (0, _errorHandling.createErrorPayload)(result.error || 'Failed to create bodied sync block'));
|
|
289
|
+
}
|
|
277
290
|
}
|
|
278
291
|
}).catch(function (error) {
|
|
279
|
-
var _this4$fireAnalyticsE2;
|
|
280
292
|
_this4.commitPendingCreation(false);
|
|
281
293
|
(0, _monitoring.logException)(error, {
|
|
282
294
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
283
295
|
});
|
|
284
|
-
|
|
296
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_dogfooding')) {
|
|
297
|
+
var _this4$createExperien2;
|
|
298
|
+
(_this4$createExperien2 = _this4.createExperience) === null || _this4$createExperien2 === void 0 || _this4$createExperien2.failure({
|
|
299
|
+
reason: error.message
|
|
300
|
+
});
|
|
301
|
+
} else {
|
|
302
|
+
var _this4$fireAnalyticsE2;
|
|
303
|
+
(_this4$fireAnalyticsE2 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE2 === void 0 || _this4$fireAnalyticsE2.call(_this4, (0, _errorHandling.createErrorPayload)(error.message));
|
|
304
|
+
}
|
|
285
305
|
});
|
|
286
306
|
this.registerPendingCreation(resourceId);
|
|
287
307
|
} catch (error) {
|
|
288
|
-
var _this$fireAnalyticsEv3;
|
|
289
308
|
if (this.hasPendingCreation()) {
|
|
290
309
|
this.commitPendingCreation(false);
|
|
291
310
|
}
|
|
292
311
|
(0, _monitoring.logException)(error, {
|
|
293
312
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
294
313
|
});
|
|
295
|
-
|
|
314
|
+
if ((0, _platformFeatureFlags.fg)('platform_synced_block_dogfooding')) {
|
|
315
|
+
var _this$createExperienc;
|
|
316
|
+
(_this$createExperienc = this.createExperience) === null || _this$createExperienc === void 0 || _this$createExperienc.failure({
|
|
317
|
+
reason: error.message
|
|
318
|
+
});
|
|
319
|
+
} else {
|
|
320
|
+
var _this$fireAnalyticsEv3;
|
|
321
|
+
(_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, (0, _errorHandling.createErrorPayload)(error.message));
|
|
322
|
+
}
|
|
296
323
|
}
|
|
297
324
|
}
|
|
298
325
|
}, {
|
|
@@ -25,6 +25,32 @@ const mapBlockError = error => {
|
|
|
25
25
|
return SyncBlockError.Errored;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Extracts the ResourceId from a block ARI by returning the full path after synced-block/.
|
|
30
|
+
*
|
|
31
|
+
* Document ARI format from Block Service API:
|
|
32
|
+
* "ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}"
|
|
33
|
+
*
|
|
34
|
+
* ResourceId format (extracted from ARI):
|
|
35
|
+
* "{product}/{parentId}/{resourceId}" (the full path after synced-block/)
|
|
36
|
+
*
|
|
37
|
+
* Example in context:
|
|
38
|
+
* Input: "ari:cloud:blocks:{uuid}:synced-block/confluence-page/{pageId}/{resourceId}"
|
|
39
|
+
* Output: "confluence-page/{pageId}/{resourceId}"
|
|
40
|
+
*
|
|
41
|
+
* @param blockAri - The block ARI string from Block Service API
|
|
42
|
+
* @returns The ResourceId (full path after synced-block/)
|
|
43
|
+
*/
|
|
44
|
+
export const blockAriToResourceId = blockAri => {
|
|
45
|
+
// Validate ARI format and extract resourceId using regex
|
|
46
|
+
// Format: ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}
|
|
47
|
+
// The regex captures the full path after synced-block/
|
|
48
|
+
// e.g. ari:cloud:blocks:DUMMY-a5a01d21-1cc3-4f29-9565-f2bb8cd969f5:synced-block/confluence-page/455232061495/e8cf64e3-1b6e-489b-ad86-8465b0905bb4
|
|
49
|
+
// should return confluence-page/455232061495/e8cf64e3-1b6e-489b-ad86-8465b0905bb4
|
|
50
|
+
const match = blockAri.match(/^ari:cloud:blocks:.*:synced-block\/(.+)$/);
|
|
51
|
+
return (match === null || match === void 0 ? void 0 : match[1]) || null;
|
|
52
|
+
};
|
|
53
|
+
|
|
28
54
|
// convert BlockContentResponse to SyncBlockData
|
|
29
55
|
// throws exception if JSON parsing fails
|
|
30
56
|
// what's missing from BlockContentResponse to SyncBlockData:
|
|
@@ -32,9 +58,9 @@ const mapBlockError = error => {
|
|
|
32
58
|
// - sourceURL
|
|
33
59
|
// - sourceTitle
|
|
34
60
|
// - isSynced
|
|
35
|
-
const convertToSyncBlockData = data => {
|
|
61
|
+
export const convertToSyncBlockData = (data, resourceId) => {
|
|
36
62
|
let createdAt;
|
|
37
|
-
if (data.createdAt) {
|
|
63
|
+
if (data.createdAt !== undefined && data.createdAt !== null) {
|
|
38
64
|
try {
|
|
39
65
|
// BE returns microseconds, convert to milliseconds
|
|
40
66
|
// BE should fix this in the future
|
|
@@ -51,7 +77,7 @@ const convertToSyncBlockData = data => {
|
|
|
51
77
|
createdAt,
|
|
52
78
|
createdBy: data.createdBy,
|
|
53
79
|
product: data.product,
|
|
54
|
-
resourceId
|
|
80
|
+
resourceId,
|
|
55
81
|
sourceAri: data.sourceAri
|
|
56
82
|
};
|
|
57
83
|
};
|
|
@@ -71,9 +97,17 @@ export const fetchReferences = async documentAri => {
|
|
|
71
97
|
} = response || {};
|
|
72
98
|
const blocksInstances = (blocks || []).map(blockContentResponse => {
|
|
73
99
|
try {
|
|
100
|
+
const resourceId = blockAriToResourceId(blockContentResponse.blockAri);
|
|
101
|
+
if (!resourceId) {
|
|
102
|
+
// could not extract resourceId from blockAri, return InvalidContent error
|
|
103
|
+
return {
|
|
104
|
+
error: SyncBlockError.InvalidContent,
|
|
105
|
+
resourceId: blockContentResponse.blockAri
|
|
106
|
+
};
|
|
107
|
+
}
|
|
74
108
|
return {
|
|
75
|
-
data: convertToSyncBlockData(blockContentResponse),
|
|
76
|
-
resourceId
|
|
109
|
+
data: convertToSyncBlockData(blockContentResponse, resourceId),
|
|
110
|
+
resourceId
|
|
77
111
|
};
|
|
78
112
|
} catch {
|
|
79
113
|
// JSON parsing error, return InvalidContent error
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
4
|
import { SyncBlockError } from '../common/types';
|
|
4
5
|
import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload } from '../utils/errorHandling';
|
|
5
6
|
import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
|
|
@@ -22,6 +23,9 @@ export class SourceSyncBlockStoreManager {
|
|
|
22
23
|
setFireAnalyticsEvent(fireAnalyticsEvent) {
|
|
23
24
|
this.fireAnalyticsEvent = fireAnalyticsEvent;
|
|
24
25
|
}
|
|
26
|
+
setCreateExperience(createExperience) {
|
|
27
|
+
this.createExperience = createExperience;
|
|
28
|
+
}
|
|
25
29
|
isSourceBlock(node) {
|
|
26
30
|
return node.type.name === 'bodiedSyncBlock';
|
|
27
31
|
}
|
|
@@ -201,28 +205,49 @@ export class SourceSyncBlockStoreManager {
|
|
|
201
205
|
if (resourceId) {
|
|
202
206
|
this.commitPendingCreation(true);
|
|
203
207
|
} else {
|
|
204
|
-
var _this$fireAnalyticsEv4;
|
|
205
208
|
this.commitPendingCreation(false);
|
|
206
|
-
|
|
209
|
+
if (fg('platform_synced_block_dogfooding')) {
|
|
210
|
+
var _this$createExperienc;
|
|
211
|
+
(_this$createExperienc = this.createExperience) === null || _this$createExperienc === void 0 ? void 0 : _this$createExperienc.failure({
|
|
212
|
+
reason: result.error || 'Failed to create bodied sync block'
|
|
213
|
+
});
|
|
214
|
+
} else {
|
|
215
|
+
var _this$fireAnalyticsEv4;
|
|
216
|
+
(_this$fireAnalyticsEv4 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv4 === void 0 ? void 0 : _this$fireAnalyticsEv4.call(this, createErrorPayload(result.error || 'Failed to create bodied sync block'));
|
|
217
|
+
}
|
|
207
218
|
}
|
|
208
219
|
}).catch(error => {
|
|
209
|
-
var _this$fireAnalyticsEv5;
|
|
210
220
|
this.commitPendingCreation(false);
|
|
211
221
|
logException(error, {
|
|
212
222
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
213
223
|
});
|
|
214
|
-
|
|
224
|
+
if (fg('platform_synced_block_dogfooding')) {
|
|
225
|
+
var _this$createExperienc2;
|
|
226
|
+
(_this$createExperienc2 = this.createExperience) === null || _this$createExperienc2 === void 0 ? void 0 : _this$createExperienc2.failure({
|
|
227
|
+
reason: error.message
|
|
228
|
+
});
|
|
229
|
+
} else {
|
|
230
|
+
var _this$fireAnalyticsEv5;
|
|
231
|
+
(_this$fireAnalyticsEv5 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv5 === void 0 ? void 0 : _this$fireAnalyticsEv5.call(this, createErrorPayload(error.message));
|
|
232
|
+
}
|
|
215
233
|
});
|
|
216
234
|
this.registerPendingCreation(resourceId);
|
|
217
235
|
} catch (error) {
|
|
218
|
-
var _this$fireAnalyticsEv6;
|
|
219
236
|
if (this.hasPendingCreation()) {
|
|
220
237
|
this.commitPendingCreation(false);
|
|
221
238
|
}
|
|
222
239
|
logException(error, {
|
|
223
240
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
224
241
|
});
|
|
225
|
-
|
|
242
|
+
if (fg('platform_synced_block_dogfooding')) {
|
|
243
|
+
var _this$createExperienc3;
|
|
244
|
+
(_this$createExperienc3 = this.createExperience) === null || _this$createExperienc3 === void 0 ? void 0 : _this$createExperienc3.failure({
|
|
245
|
+
reason: error.message
|
|
246
|
+
});
|
|
247
|
+
} else {
|
|
248
|
+
var _this$fireAnalyticsEv6;
|
|
249
|
+
(_this$fireAnalyticsEv6 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv6 === void 0 ? void 0 : _this$fireAnalyticsEv6.call(this, createErrorPayload(error.message));
|
|
250
|
+
}
|
|
226
251
|
}
|
|
227
252
|
}
|
|
228
253
|
async delete(syncBlockIds, onDelete, onDeleteCompleted) {
|
|
@@ -33,6 +33,32 @@ var mapBlockError = function mapBlockError(error) {
|
|
|
33
33
|
return SyncBlockError.Errored;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Extracts the ResourceId from a block ARI by returning the full path after synced-block/.
|
|
38
|
+
*
|
|
39
|
+
* Document ARI format from Block Service API:
|
|
40
|
+
* "ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}"
|
|
41
|
+
*
|
|
42
|
+
* ResourceId format (extracted from ARI):
|
|
43
|
+
* "{product}/{parentId}/{resourceId}" (the full path after synced-block/)
|
|
44
|
+
*
|
|
45
|
+
* Example in context:
|
|
46
|
+
* Input: "ari:cloud:blocks:{uuid}:synced-block/confluence-page/{pageId}/{resourceId}"
|
|
47
|
+
* Output: "confluence-page/{pageId}/{resourceId}"
|
|
48
|
+
*
|
|
49
|
+
* @param blockAri - The block ARI string from Block Service API
|
|
50
|
+
* @returns The ResourceId (full path after synced-block/)
|
|
51
|
+
*/
|
|
52
|
+
export var blockAriToResourceId = function blockAriToResourceId(blockAri) {
|
|
53
|
+
// Validate ARI format and extract resourceId using regex
|
|
54
|
+
// Format: ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}
|
|
55
|
+
// The regex captures the full path after synced-block/
|
|
56
|
+
// e.g. ari:cloud:blocks:DUMMY-a5a01d21-1cc3-4f29-9565-f2bb8cd969f5:synced-block/confluence-page/455232061495/e8cf64e3-1b6e-489b-ad86-8465b0905bb4
|
|
57
|
+
// should return confluence-page/455232061495/e8cf64e3-1b6e-489b-ad86-8465b0905bb4
|
|
58
|
+
var match = blockAri.match(/^ari:cloud:blocks:.*:synced-block\/(.+)$/);
|
|
59
|
+
return (match === null || match === void 0 ? void 0 : match[1]) || null;
|
|
60
|
+
};
|
|
61
|
+
|
|
36
62
|
// convert BlockContentResponse to SyncBlockData
|
|
37
63
|
// throws exception if JSON parsing fails
|
|
38
64
|
// what's missing from BlockContentResponse to SyncBlockData:
|
|
@@ -40,9 +66,9 @@ var mapBlockError = function mapBlockError(error) {
|
|
|
40
66
|
// - sourceURL
|
|
41
67
|
// - sourceTitle
|
|
42
68
|
// - isSynced
|
|
43
|
-
var convertToSyncBlockData = function convertToSyncBlockData(data) {
|
|
69
|
+
export var convertToSyncBlockData = function convertToSyncBlockData(data, resourceId) {
|
|
44
70
|
var createdAt;
|
|
45
|
-
if (data.createdAt) {
|
|
71
|
+
if (data.createdAt !== undefined && data.createdAt !== null) {
|
|
46
72
|
try {
|
|
47
73
|
// BE returns microseconds, convert to milliseconds
|
|
48
74
|
// BE should fix this in the future
|
|
@@ -59,7 +85,7 @@ var convertToSyncBlockData = function convertToSyncBlockData(data) {
|
|
|
59
85
|
createdAt: createdAt,
|
|
60
86
|
createdBy: data.createdBy,
|
|
61
87
|
product: data.product,
|
|
62
|
-
resourceId:
|
|
88
|
+
resourceId: resourceId,
|
|
63
89
|
sourceAri: data.sourceAri
|
|
64
90
|
};
|
|
65
91
|
};
|
|
@@ -90,9 +116,17 @@ export var fetchReferences = /*#__PURE__*/function () {
|
|
|
90
116
|
_ref2 = response || {}, blocks = _ref2.blocks, errors = _ref2.errors;
|
|
91
117
|
blocksInstances = (blocks || []).map(function (blockContentResponse) {
|
|
92
118
|
try {
|
|
119
|
+
var resourceId = blockAriToResourceId(blockContentResponse.blockAri);
|
|
120
|
+
if (!resourceId) {
|
|
121
|
+
// could not extract resourceId from blockAri, return InvalidContent error
|
|
122
|
+
return {
|
|
123
|
+
error: SyncBlockError.InvalidContent,
|
|
124
|
+
resourceId: blockContentResponse.blockAri
|
|
125
|
+
};
|
|
126
|
+
}
|
|
93
127
|
return {
|
|
94
|
-
data: convertToSyncBlockData(blockContentResponse),
|
|
95
|
-
resourceId:
|
|
128
|
+
data: convertToSyncBlockData(blockContentResponse, resourceId),
|
|
129
|
+
resourceId: resourceId
|
|
96
130
|
};
|
|
97
131
|
} catch (_unused) {
|
|
98
132
|
// JSON parsing error, return InvalidContent error
|
|
@@ -6,6 +6,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
6
6
|
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; }
|
|
7
7
|
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; }
|
|
8
8
|
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
9
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
10
|
import { SyncBlockError } from '../common/types';
|
|
10
11
|
import { updateErrorPayload, createErrorPayload, deleteErrorPayload, updateCacheErrorPayload } from '../utils/errorHandling';
|
|
11
12
|
import { convertSyncBlockPMNodeToSyncBlockData } from '../utils/utils';
|
|
@@ -32,6 +33,11 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
32
33
|
value: function setFireAnalyticsEvent(fireAnalyticsEvent) {
|
|
33
34
|
this.fireAnalyticsEvent = fireAnalyticsEvent;
|
|
34
35
|
}
|
|
36
|
+
}, {
|
|
37
|
+
key: "setCreateExperience",
|
|
38
|
+
value: function setCreateExperience(createExperience) {
|
|
39
|
+
this.createExperience = createExperience;
|
|
40
|
+
}
|
|
35
41
|
}, {
|
|
36
42
|
key: "isSourceBlock",
|
|
37
43
|
value: function isSourceBlock(node) {
|
|
@@ -264,28 +270,49 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
264
270
|
if (resourceId) {
|
|
265
271
|
_this4.commitPendingCreation(true);
|
|
266
272
|
} else {
|
|
267
|
-
var _this4$fireAnalyticsE;
|
|
268
273
|
_this4.commitPendingCreation(false);
|
|
269
|
-
|
|
274
|
+
if (fg('platform_synced_block_dogfooding')) {
|
|
275
|
+
var _this4$createExperien;
|
|
276
|
+
(_this4$createExperien = _this4.createExperience) === null || _this4$createExperien === void 0 || _this4$createExperien.failure({
|
|
277
|
+
reason: result.error || 'Failed to create bodied sync block'
|
|
278
|
+
});
|
|
279
|
+
} else {
|
|
280
|
+
var _this4$fireAnalyticsE;
|
|
281
|
+
(_this4$fireAnalyticsE = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE === void 0 || _this4$fireAnalyticsE.call(_this4, createErrorPayload(result.error || 'Failed to create bodied sync block'));
|
|
282
|
+
}
|
|
270
283
|
}
|
|
271
284
|
}).catch(function (error) {
|
|
272
|
-
var _this4$fireAnalyticsE2;
|
|
273
285
|
_this4.commitPendingCreation(false);
|
|
274
286
|
logException(error, {
|
|
275
287
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
276
288
|
});
|
|
277
|
-
|
|
289
|
+
if (fg('platform_synced_block_dogfooding')) {
|
|
290
|
+
var _this4$createExperien2;
|
|
291
|
+
(_this4$createExperien2 = _this4.createExperience) === null || _this4$createExperien2 === void 0 || _this4$createExperien2.failure({
|
|
292
|
+
reason: error.message
|
|
293
|
+
});
|
|
294
|
+
} else {
|
|
295
|
+
var _this4$fireAnalyticsE2;
|
|
296
|
+
(_this4$fireAnalyticsE2 = _this4.fireAnalyticsEvent) === null || _this4$fireAnalyticsE2 === void 0 || _this4$fireAnalyticsE2.call(_this4, createErrorPayload(error.message));
|
|
297
|
+
}
|
|
278
298
|
});
|
|
279
299
|
this.registerPendingCreation(resourceId);
|
|
280
300
|
} catch (error) {
|
|
281
|
-
var _this$fireAnalyticsEv3;
|
|
282
301
|
if (this.hasPendingCreation()) {
|
|
283
302
|
this.commitPendingCreation(false);
|
|
284
303
|
}
|
|
285
304
|
logException(error, {
|
|
286
305
|
location: 'editor-synced-block-provider/sourceSyncBlockStoreManager'
|
|
287
306
|
});
|
|
288
|
-
|
|
307
|
+
if (fg('platform_synced_block_dogfooding')) {
|
|
308
|
+
var _this$createExperienc;
|
|
309
|
+
(_this$createExperienc = this.createExperience) === null || _this$createExperienc === void 0 || _this$createExperienc.failure({
|
|
310
|
+
reason: error.message
|
|
311
|
+
});
|
|
312
|
+
} else {
|
|
313
|
+
var _this$fireAnalyticsEv3;
|
|
314
|
+
(_this$fireAnalyticsEv3 = this.fireAnalyticsEvent) === null || _this$fireAnalyticsEv3 === void 0 || _this$fireAnalyticsEv3.call(this, createErrorPayload(error.message));
|
|
315
|
+
}
|
|
289
316
|
}
|
|
290
317
|
}
|
|
291
318
|
}, {
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
+
import { type BlockContentResponse } from '../../clients/block-service/blockService';
|
|
1
2
|
import { SyncBlockError, type ResourceId, type SyncBlockAttrs, type SyncBlockData, type SyncBlockProduct } from '../../common/types';
|
|
2
3
|
import type { ADFFetchProvider, ADFWriteProvider, DeleteSyncBlockResult, SyncBlockInstance, UpdateReferenceSyncBlockResult, WriteSyncBlockResult } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Extracts the ResourceId from a block ARI by returning the full path after synced-block/.
|
|
6
|
+
*
|
|
7
|
+
* Document ARI format from Block Service API:
|
|
8
|
+
* "ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}"
|
|
9
|
+
*
|
|
10
|
+
* ResourceId format (extracted from ARI):
|
|
11
|
+
* "{product}/{parentId}/{resourceId}" (the full path after synced-block/)
|
|
12
|
+
*
|
|
13
|
+
* Example in context:
|
|
14
|
+
* Input: "ari:cloud:blocks:{uuid}:synced-block/confluence-page/{pageId}/{resourceId}"
|
|
15
|
+
* Output: "confluence-page/{pageId}/{resourceId}"
|
|
16
|
+
*
|
|
17
|
+
* @param blockAri - The block ARI string from Block Service API
|
|
18
|
+
* @returns The ResourceId (full path after synced-block/)
|
|
19
|
+
*/
|
|
20
|
+
export declare const blockAriToResourceId: (blockAri: string) => ResourceId | null;
|
|
21
|
+
export declare const convertToSyncBlockData: (data: BlockContentResponse, resourceId: ResourceId) => SyncBlockData;
|
|
3
22
|
export declare const fetchReferences: (documentAri: string) => Promise<SyncBlockInstance[] | SyncBlockError>;
|
|
4
23
|
interface BlockServiceADFFetchProviderProps {
|
|
5
24
|
cloudId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type SyncBlockEventPayload } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import type { Experience } from '@atlaskit/editor-common/experiences';
|
|
2
3
|
import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
4
|
import { type ResourceId, type SyncBlockAttrs } from '../common/types';
|
|
4
5
|
import type { SyncBlockDataProvider } from '../providers/types';
|
|
@@ -15,8 +16,10 @@ export declare class SourceSyncBlockStoreManager {
|
|
|
15
16
|
private deletionRetryInfo?;
|
|
16
17
|
private pendingResourceId?;
|
|
17
18
|
private creationCallback?;
|
|
19
|
+
createExperience: Experience | undefined;
|
|
18
20
|
constructor(dataProvider?: SyncBlockDataProvider);
|
|
19
21
|
setFireAnalyticsEvent(fireAnalyticsEvent?: (payload: SyncBlockEventPayload) => void): void;
|
|
22
|
+
setCreateExperience(createExperience: Experience): void;
|
|
20
23
|
isSourceBlock(node: PMNode): boolean;
|
|
21
24
|
/**
|
|
22
25
|
* Add/update a sync block node to/from the local cache
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
+
import { type BlockContentResponse } from '../../clients/block-service/blockService';
|
|
1
2
|
import { SyncBlockError, type ResourceId, type SyncBlockAttrs, type SyncBlockData, type SyncBlockProduct } from '../../common/types';
|
|
2
3
|
import type { ADFFetchProvider, ADFWriteProvider, DeleteSyncBlockResult, SyncBlockInstance, UpdateReferenceSyncBlockResult, WriteSyncBlockResult } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Extracts the ResourceId from a block ARI by returning the full path after synced-block/.
|
|
6
|
+
*
|
|
7
|
+
* Document ARI format from Block Service API:
|
|
8
|
+
* "ari:cloud:blocks:{uuid}:synced-block/{product}/{parentId}/{resourceId}"
|
|
9
|
+
*
|
|
10
|
+
* ResourceId format (extracted from ARI):
|
|
11
|
+
* "{product}/{parentId}/{resourceId}" (the full path after synced-block/)
|
|
12
|
+
*
|
|
13
|
+
* Example in context:
|
|
14
|
+
* Input: "ari:cloud:blocks:{uuid}:synced-block/confluence-page/{pageId}/{resourceId}"
|
|
15
|
+
* Output: "confluence-page/{pageId}/{resourceId}"
|
|
16
|
+
*
|
|
17
|
+
* @param blockAri - The block ARI string from Block Service API
|
|
18
|
+
* @returns The ResourceId (full path after synced-block/)
|
|
19
|
+
*/
|
|
20
|
+
export declare const blockAriToResourceId: (blockAri: string) => ResourceId | null;
|
|
21
|
+
export declare const convertToSyncBlockData: (data: BlockContentResponse, resourceId: ResourceId) => SyncBlockData;
|
|
3
22
|
export declare const fetchReferences: (documentAri: string) => Promise<SyncBlockInstance[] | SyncBlockError>;
|
|
4
23
|
interface BlockServiceADFFetchProviderProps {
|
|
5
24
|
cloudId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type SyncBlockEventPayload } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import type { Experience } from '@atlaskit/editor-common/experiences';
|
|
2
3
|
import { type Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
4
|
import { type ResourceId, type SyncBlockAttrs } from '../common/types';
|
|
4
5
|
import type { SyncBlockDataProvider } from '../providers/types';
|
|
@@ -15,8 +16,10 @@ export declare class SourceSyncBlockStoreManager {
|
|
|
15
16
|
private deletionRetryInfo?;
|
|
16
17
|
private pendingResourceId?;
|
|
17
18
|
private creationCallback?;
|
|
19
|
+
createExperience: Experience | undefined;
|
|
18
20
|
constructor(dataProvider?: SyncBlockDataProvider);
|
|
19
21
|
setFireAnalyticsEvent(fireAnalyticsEvent?: (payload: SyncBlockEventPayload) => void): void;
|
|
22
|
+
setCreateExperience(createExperience: Experience): void;
|
|
20
23
|
isSourceBlock(node: PMNode): boolean;
|
|
21
24
|
/**
|
|
22
25
|
* Add/update a sync block node to/from the local cache
|
package/package.json
CHANGED