@atlaskit/editor-synced-block-provider 2.7.4 → 2.9.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 +14 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/providers/block-service/blockServiceAPI.js +238 -0
- package/dist/cjs/providers/confluence/confluenceContentAPI.js +5 -0
- package/dist/cjs/providers/syncBlockProvider.js +5 -0
- package/dist/cjs/store-manager/sourceSyncBlockStoreManager.js +2 -5
- package/dist/cjs/utils/ari.js +32 -4
- package/dist/cjs/utils/blockService.js +168 -0
- package/dist/es2019/index.js +2 -1
- package/dist/es2019/providers/block-service/blockServiceAPI.js +148 -0
- package/dist/es2019/providers/confluence/confluenceContentAPI.js +4 -1
- package/dist/es2019/providers/syncBlockProvider.js +3 -0
- package/dist/es2019/store-manager/sourceSyncBlockStoreManager.js +2 -5
- package/dist/es2019/utils/ari.js +31 -1
- package/dist/es2019/utils/blockService.js +71 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/providers/block-service/blockServiceAPI.js +231 -0
- package/dist/esm/providers/confluence/confluenceContentAPI.js +6 -1
- package/dist/esm/providers/syncBlockProvider.js +5 -0
- package/dist/esm/store-manager/sourceSyncBlockStoreManager.js +2 -5
- package/dist/esm/utils/ari.js +31 -3
- package/dist/esm/utils/blockService.js +161 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/providers/block-service/blockServiceAPI.d.ts +21 -0
- package/dist/types/providers/confluence/confluenceContentAPI.d.ts +1 -0
- package/dist/types/providers/syncBlockProvider.d.ts +1 -0
- package/dist/types/providers/types.d.ts +8 -0
- package/dist/types/utils/ari.d.ts +15 -1
- package/dist/types/utils/blockService.d.ts +39 -0
- package/dist/types-ts4.5/index.d.ts +2 -1
- package/dist/types-ts4.5/providers/block-service/blockServiceAPI.d.ts +21 -0
- package/dist/types-ts4.5/providers/confluence/confluenceContentAPI.d.ts +1 -0
- package/dist/types-ts4.5/providers/syncBlockProvider.d.ts +1 -0
- package/dist/types-ts4.5/providers/types.d.ts +8 -0
- package/dist/types-ts4.5/utils/ari.d.ts +15 -1
- package/dist/types-ts4.5/utils/blockService.d.ts +39 -0
- package/package.json +8 -2
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { SyncBlockError } from '../../common/types';
|
|
3
|
+
import { blockResourceIdFromSourceAndLocalId, getLocalIdFromResourceId } from '../../utils/ari';
|
|
4
|
+
import { BlockError, createSyncedBlock, deleteSyncedBlock, getSyncedBlockContent, updateSyncedBlock } from '../../utils/blockService';
|
|
5
|
+
import { stringifyError } from '../../utils/errorHandling';
|
|
6
|
+
const mapBlockError = error => {
|
|
7
|
+
switch (error.status) {
|
|
8
|
+
case 403:
|
|
9
|
+
return SyncBlockError.Forbidden;
|
|
10
|
+
case 404:
|
|
11
|
+
return SyncBlockError.NotFound;
|
|
12
|
+
}
|
|
13
|
+
return SyncBlockError.Errored;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* ADFFetchProvider implementation that fetches synced block data from Block Service API
|
|
18
|
+
*/
|
|
19
|
+
class BlockServiceADFFetchProvider {
|
|
20
|
+
// resourceId is the ARI of the block. E.G ari:cloud:blocks:site-123:synced-block/uuid-456
|
|
21
|
+
// in the content API provider, this was the concatenation of the source document's ARI and the local ID. E.G ari:cloud:confluence:site-123:page/pageId/uuid-456
|
|
22
|
+
async fetchData(resourceId) {
|
|
23
|
+
const localId = getLocalIdFromResourceId(resourceId);
|
|
24
|
+
try {
|
|
25
|
+
const blockContentResponse = await getSyncedBlockContent({
|
|
26
|
+
blockAri: resourceId
|
|
27
|
+
});
|
|
28
|
+
const value = blockContentResponse.content;
|
|
29
|
+
if (!value) {
|
|
30
|
+
return {
|
|
31
|
+
error: SyncBlockError.NotFound,
|
|
32
|
+
resourceId
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Parse the synced block content from the response's content
|
|
37
|
+
const syncedBlockData = JSON.parse(value);
|
|
38
|
+
return {
|
|
39
|
+
data: {
|
|
40
|
+
content: syncedBlockData,
|
|
41
|
+
resourceId,
|
|
42
|
+
blockInstanceId: localId
|
|
43
|
+
},
|
|
44
|
+
resourceId
|
|
45
|
+
};
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error instanceof BlockError) {
|
|
48
|
+
return {
|
|
49
|
+
error: mapBlockError(error),
|
|
50
|
+
resourceId
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
error: SyncBlockError.Errored,
|
|
55
|
+
resourceId
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
63
|
+
*/
|
|
64
|
+
class BlockServiceADFWriteProvider {
|
|
65
|
+
// it will first try to update and if it can't (404) then it will try to create
|
|
66
|
+
async writeData(data) {
|
|
67
|
+
const {
|
|
68
|
+
resourceId
|
|
69
|
+
} = data;
|
|
70
|
+
try {
|
|
71
|
+
// Try update existing block's content
|
|
72
|
+
await updateSyncedBlock({
|
|
73
|
+
blockAri: resourceId,
|
|
74
|
+
content: JSON.stringify(data.content)
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
resourceId
|
|
78
|
+
};
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error instanceof BlockError) {
|
|
81
|
+
if (error.status === 404) {
|
|
82
|
+
// Create the block
|
|
83
|
+
await createSyncedBlock({
|
|
84
|
+
blockAri: resourceId,
|
|
85
|
+
blockInstanceId: data.blockInstanceId,
|
|
86
|
+
sourceAri: resourceId,
|
|
87
|
+
product: 'confluence-page',
|
|
88
|
+
content: JSON.stringify(data.content)
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
return {
|
|
92
|
+
error: mapBlockError(error),
|
|
93
|
+
resourceId
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
error: stringifyError(error),
|
|
99
|
+
resourceId
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// soft deletes the source synced block
|
|
105
|
+
async deleteData(resourceId) {
|
|
106
|
+
try {
|
|
107
|
+
await deleteSyncedBlock({
|
|
108
|
+
blockAri: resourceId
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
resourceId,
|
|
112
|
+
success: true,
|
|
113
|
+
error: undefined
|
|
114
|
+
};
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error instanceof BlockError) {
|
|
117
|
+
return {
|
|
118
|
+
resourceId,
|
|
119
|
+
success: false,
|
|
120
|
+
error: mapBlockError(error)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
resourceId,
|
|
125
|
+
success: false,
|
|
126
|
+
error: stringifyError(error)
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
generateResourceId(sourceId, localId) {
|
|
131
|
+
return blockResourceIdFromSourceAndLocalId(sourceId, localId);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Factory function to create both providers with shared configuration
|
|
137
|
+
*/
|
|
138
|
+
const createBlockServiceAPIProviders = () => {
|
|
139
|
+
const fetchProvider = new BlockServiceADFFetchProvider();
|
|
140
|
+
const writeProvider = new BlockServiceADFWriteProvider();
|
|
141
|
+
return {
|
|
142
|
+
fetchProvider,
|
|
143
|
+
writeProvider
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
export const useMemoizedBlockServiceAPIProviders = () => {
|
|
147
|
+
return useMemo(createBlockServiceAPIProviders, []);
|
|
148
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { SyncBlockError } from '../../common/types';
|
|
4
|
-
import { getLocalIdFromAri, getPageIdAndTypeFromAri } from '../../utils/ari';
|
|
4
|
+
import { getLocalIdFromAri, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from '../../utils/ari';
|
|
5
5
|
import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../utils/contentProperty';
|
|
6
6
|
import { stringifyError } from '../../utils/errorHandling';
|
|
7
7
|
import { isBlogPageType } from '../../utils/utils';
|
|
@@ -227,6 +227,9 @@ class ConfluenceADFWriteProvider {
|
|
|
227
227
|
error: deleteResult.errors.join()
|
|
228
228
|
};
|
|
229
229
|
}
|
|
230
|
+
generateResourceId(sourceId, localId) {
|
|
231
|
+
return resourceIdFromSourceAndLocalId(sourceId, localId);
|
|
232
|
+
}
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
/**
|
|
@@ -99,6 +99,9 @@ export class SyncBlockProvider extends SyncBlockDataProvider {
|
|
|
99
99
|
}
|
|
100
100
|
return pageARI ? fetchSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
|
|
101
101
|
}
|
|
102
|
+
generateResourceId(sourceId, localId) {
|
|
103
|
+
return this.writeProvider.generateResourceId(sourceId, localId);
|
|
104
|
+
}
|
|
102
105
|
}
|
|
103
106
|
export const useMemoizedSyncedBlockProvider = (fetchProvider, writeProvider, sourceId) => {
|
|
104
107
|
return useMemo(() => {
|
|
@@ -2,7 +2,6 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
3
3
|
import uuid from 'uuid';
|
|
4
4
|
import { rebaseTransaction } from '../common/rebase-transaction';
|
|
5
|
-
import { resourceIdFromSourceAndLocalId } from '../utils/ari';
|
|
6
5
|
import { convertSyncBlockPMNodeToSyncBlockData, createBodiedSyncBlockNode } from '../utils/utils';
|
|
7
6
|
export class SourceSyncBlockStoreManager {
|
|
8
7
|
constructor(dataProvider) {
|
|
@@ -106,12 +105,10 @@ export class SourceSyncBlockStoreManager {
|
|
|
106
105
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
107
106
|
const localId = uuid();
|
|
108
107
|
const sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
|
|
109
|
-
if (!sourceId) {
|
|
108
|
+
if (!this.dataProvider || !sourceId) {
|
|
110
109
|
throw new Error('Provider of sync block plugin is not set');
|
|
111
110
|
}
|
|
112
|
-
|
|
113
|
-
// This should be generated by the data provider implementation as it differs between data providers
|
|
114
|
-
const resourceId = resourceIdFromSourceAndLocalId(sourceId, localId);
|
|
111
|
+
const resourceId = this.dataProvider.generateResourceId(sourceId, localId);
|
|
115
112
|
return {
|
|
116
113
|
resourceId,
|
|
117
114
|
localId
|
package/dist/es2019/utils/ari.js
CHANGED
|
@@ -25,7 +25,37 @@ export const getPageARIFromResourceId = resourceId => {
|
|
|
25
25
|
}
|
|
26
26
|
throw new Error(`Invalid resourceId: ${resourceId}`);
|
|
27
27
|
};
|
|
28
|
-
export const getContentPropertyAri = (contentPropertyId, cloudId) => `ari:cloud:confluence:${cloudId}:content/${contentPropertyId}`;
|
|
29
28
|
export const resourceIdFromSourceAndLocalId = (sourceId, localId) => {
|
|
30
29
|
return sourceId + '/' + localId;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* For the following functions, they are used for the block service API provider.
|
|
34
|
+
* The resourceId/blockResourceId always refers to the block ARI.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param sourceId - the ARI of the document. E.G ari:cloud:confluence:cloudId:page/pageId
|
|
39
|
+
* @param localId - the localId of the block node. A randomly generated UUID
|
|
40
|
+
* @returns the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
|
|
41
|
+
*/
|
|
42
|
+
export const blockResourceIdFromSourceAndLocalId = (sourceId, localId) => {
|
|
43
|
+
const match = sourceId.match(/ari:cloud:confluence:([^:]+):(page|blogpost)\/.*/);
|
|
44
|
+
if (!(match !== null && match !== void 0 && match[1])) {
|
|
45
|
+
throw new Error(`Invalid source ARI: ${sourceId}`);
|
|
46
|
+
}
|
|
47
|
+
const cloudId = match[1];
|
|
48
|
+
return `ari:cloud:blocks:${cloudId}:synced-block/${localId}`;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param ari - the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
|
|
53
|
+
* @returns the localId of the block node. A randomly generated UUID
|
|
54
|
+
*/
|
|
55
|
+
export const getLocalIdFromResourceId = ari => {
|
|
56
|
+
const match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+\/([a-zA-Z0-9-]+)/);
|
|
57
|
+
if (match !== null && match !== void 0 && match[2]) {
|
|
58
|
+
return match[2];
|
|
59
|
+
}
|
|
60
|
+
throw new Error(`Invalid page ARI: ${ari}`);
|
|
31
61
|
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const COMMON_HEADERS = {
|
|
2
|
+
'Content-Type': 'application/json',
|
|
3
|
+
Accept: 'application/json'
|
|
4
|
+
};
|
|
5
|
+
const BLOCK_SERVICE_API_URL = '/gateway/api/blocks/v1';
|
|
6
|
+
export class BlockError extends Error {
|
|
7
|
+
constructor(status) {
|
|
8
|
+
super(`Block error`);
|
|
9
|
+
this.status = status;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export const getSyncedBlockContent = async ({
|
|
13
|
+
blockAri
|
|
14
|
+
}) => {
|
|
15
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
16
|
+
method: 'GET',
|
|
17
|
+
headers: COMMON_HEADERS
|
|
18
|
+
});
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
throw new BlockError(response.status);
|
|
21
|
+
}
|
|
22
|
+
return await response.json();
|
|
23
|
+
};
|
|
24
|
+
export const deleteSyncedBlock = async ({
|
|
25
|
+
blockAri
|
|
26
|
+
}) => {
|
|
27
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
28
|
+
method: 'DELETE',
|
|
29
|
+
headers: COMMON_HEADERS
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new BlockError(response.status);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
export const updateSyncedBlock = async ({
|
|
36
|
+
blockAri,
|
|
37
|
+
content
|
|
38
|
+
}) => {
|
|
39
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
40
|
+
method: 'PUT',
|
|
41
|
+
headers: COMMON_HEADERS,
|
|
42
|
+
body: JSON.stringify({
|
|
43
|
+
content
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new BlockError(response.status);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
export const createSyncedBlock = async ({
|
|
51
|
+
blockAri,
|
|
52
|
+
blockInstanceId,
|
|
53
|
+
sourceAri,
|
|
54
|
+
product,
|
|
55
|
+
content
|
|
56
|
+
}) => {
|
|
57
|
+
const response = await fetch(`${BLOCK_SERVICE_API_URL}/block/${blockAri}`, {
|
|
58
|
+
method: 'POST',
|
|
59
|
+
headers: COMMON_HEADERS,
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
blockInstanceId,
|
|
62
|
+
sourceAri,
|
|
63
|
+
product,
|
|
64
|
+
content
|
|
65
|
+
})
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new BlockError(response.status);
|
|
69
|
+
}
|
|
70
|
+
return await response.json();
|
|
71
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -5,10 +5,11 @@ export { SyncBlockError } from './common/types';
|
|
|
5
5
|
export { useFetchSyncBlockData } from './hooks/useFetchSyncBlockData';
|
|
6
6
|
export { useFetchSyncBlockTitle } from './hooks/useFetchSyncBlockTitle';
|
|
7
7
|
export { useHandleContentChanges } from './hooks/useHandleContentChanges';
|
|
8
|
+
export { useMemoizedBlockServiceAPIProviders } from './providers/block-service/blockServiceAPI';
|
|
8
9
|
export { createContentAPIProvidersWithDefaultKey, useMemoizedContentAPIProviders } from './providers/confluence/confluenceContentAPI';
|
|
9
10
|
export { SyncBlockProvider as SyncedBlockProvider, useMemoizedSyncedBlockProvider } from './providers/syncBlockProvider';
|
|
10
11
|
export { ReferenceSyncBlockStoreManager } from './store-manager/referenceSyncBlockStoreManager';
|
|
11
12
|
export { SyncBlockStoreManager } from './store-manager/syncBlockStoreManager';
|
|
12
|
-
export { getConfluencePageAri, getPageIdAndTypeFromAri } from './utils/ari';
|
|
13
|
+
export { blockResourceIdFromSourceAndLocalId, getConfluencePageAri, getLocalIdFromAri, getLocalIdFromResourceId, getPageARIFromResourceId, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from './utils/ari';
|
|
13
14
|
export { createSyncBlockNode, convertSyncBlockPMNodeToSyncBlockData, convertSyncBlockJSONNodeToSyncBlockNode } from './utils/utils';
|
|
14
15
|
export { resolveSyncBlockInstance } from './utils/resolveSyncBlockInstance';
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
4
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
import { SyncBlockError } from '../../common/types';
|
|
7
|
+
import { blockResourceIdFromSourceAndLocalId, getLocalIdFromResourceId } from '../../utils/ari';
|
|
8
|
+
import { BlockError, createSyncedBlock, deleteSyncedBlock, getSyncedBlockContent, updateSyncedBlock } from '../../utils/blockService';
|
|
9
|
+
import { stringifyError } from '../../utils/errorHandling';
|
|
10
|
+
var mapBlockError = function mapBlockError(error) {
|
|
11
|
+
switch (error.status) {
|
|
12
|
+
case 403:
|
|
13
|
+
return SyncBlockError.Forbidden;
|
|
14
|
+
case 404:
|
|
15
|
+
return SyncBlockError.NotFound;
|
|
16
|
+
}
|
|
17
|
+
return SyncBlockError.Errored;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* ADFFetchProvider implementation that fetches synced block data from Block Service API
|
|
22
|
+
*/
|
|
23
|
+
var BlockServiceADFFetchProvider = /*#__PURE__*/function () {
|
|
24
|
+
function BlockServiceADFFetchProvider() {
|
|
25
|
+
_classCallCheck(this, BlockServiceADFFetchProvider);
|
|
26
|
+
}
|
|
27
|
+
return _createClass(BlockServiceADFFetchProvider, [{
|
|
28
|
+
key: "fetchData",
|
|
29
|
+
value: // resourceId is the ARI of the block. E.G ari:cloud:blocks:site-123:synced-block/uuid-456
|
|
30
|
+
// in the content API provider, this was the concatenation of the source document's ARI and the local ID. E.G ari:cloud:confluence:site-123:page/pageId/uuid-456
|
|
31
|
+
function () {
|
|
32
|
+
var _fetchData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(resourceId) {
|
|
33
|
+
var localId, blockContentResponse, value, syncedBlockData;
|
|
34
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
35
|
+
while (1) switch (_context.prev = _context.next) {
|
|
36
|
+
case 0:
|
|
37
|
+
localId = getLocalIdFromResourceId(resourceId);
|
|
38
|
+
_context.prev = 1;
|
|
39
|
+
_context.next = 4;
|
|
40
|
+
return getSyncedBlockContent({
|
|
41
|
+
blockAri: resourceId
|
|
42
|
+
});
|
|
43
|
+
case 4:
|
|
44
|
+
blockContentResponse = _context.sent;
|
|
45
|
+
value = blockContentResponse.content;
|
|
46
|
+
if (value) {
|
|
47
|
+
_context.next = 8;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
return _context.abrupt("return", {
|
|
51
|
+
error: SyncBlockError.NotFound,
|
|
52
|
+
resourceId: resourceId
|
|
53
|
+
});
|
|
54
|
+
case 8:
|
|
55
|
+
// Parse the synced block content from the response's content
|
|
56
|
+
syncedBlockData = JSON.parse(value);
|
|
57
|
+
return _context.abrupt("return", {
|
|
58
|
+
data: {
|
|
59
|
+
content: syncedBlockData,
|
|
60
|
+
resourceId: resourceId,
|
|
61
|
+
blockInstanceId: localId
|
|
62
|
+
},
|
|
63
|
+
resourceId: resourceId
|
|
64
|
+
});
|
|
65
|
+
case 12:
|
|
66
|
+
_context.prev = 12;
|
|
67
|
+
_context.t0 = _context["catch"](1);
|
|
68
|
+
if (!(_context.t0 instanceof BlockError)) {
|
|
69
|
+
_context.next = 16;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
return _context.abrupt("return", {
|
|
73
|
+
error: mapBlockError(_context.t0),
|
|
74
|
+
resourceId: resourceId
|
|
75
|
+
});
|
|
76
|
+
case 16:
|
|
77
|
+
return _context.abrupt("return", {
|
|
78
|
+
error: SyncBlockError.Errored,
|
|
79
|
+
resourceId: resourceId
|
|
80
|
+
});
|
|
81
|
+
case 17:
|
|
82
|
+
case "end":
|
|
83
|
+
return _context.stop();
|
|
84
|
+
}
|
|
85
|
+
}, _callee, null, [[1, 12]]);
|
|
86
|
+
}));
|
|
87
|
+
function fetchData(_x) {
|
|
88
|
+
return _fetchData.apply(this, arguments);
|
|
89
|
+
}
|
|
90
|
+
return fetchData;
|
|
91
|
+
}()
|
|
92
|
+
}]);
|
|
93
|
+
}();
|
|
94
|
+
/**
|
|
95
|
+
* ADFWriteProvider implementation that writes synced block data to Block Service API
|
|
96
|
+
*/
|
|
97
|
+
var BlockServiceADFWriteProvider = /*#__PURE__*/function () {
|
|
98
|
+
function BlockServiceADFWriteProvider() {
|
|
99
|
+
_classCallCheck(this, BlockServiceADFWriteProvider);
|
|
100
|
+
}
|
|
101
|
+
return _createClass(BlockServiceADFWriteProvider, [{
|
|
102
|
+
key: "writeData",
|
|
103
|
+
value: // it will first try to update and if it can't (404) then it will try to create
|
|
104
|
+
function () {
|
|
105
|
+
var _writeData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(data) {
|
|
106
|
+
var resourceId;
|
|
107
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
108
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
109
|
+
case 0:
|
|
110
|
+
resourceId = data.resourceId;
|
|
111
|
+
_context2.prev = 1;
|
|
112
|
+
_context2.next = 4;
|
|
113
|
+
return updateSyncedBlock({
|
|
114
|
+
blockAri: resourceId,
|
|
115
|
+
content: JSON.stringify(data.content)
|
|
116
|
+
});
|
|
117
|
+
case 4:
|
|
118
|
+
return _context2.abrupt("return", {
|
|
119
|
+
resourceId: resourceId
|
|
120
|
+
});
|
|
121
|
+
case 7:
|
|
122
|
+
_context2.prev = 7;
|
|
123
|
+
_context2.t0 = _context2["catch"](1);
|
|
124
|
+
if (!(_context2.t0 instanceof BlockError)) {
|
|
125
|
+
_context2.next = 16;
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
if (!(_context2.t0.status === 404)) {
|
|
129
|
+
_context2.next = 15;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
_context2.next = 13;
|
|
133
|
+
return createSyncedBlock({
|
|
134
|
+
blockAri: resourceId,
|
|
135
|
+
blockInstanceId: data.blockInstanceId,
|
|
136
|
+
sourceAri: resourceId,
|
|
137
|
+
product: 'confluence-page',
|
|
138
|
+
content: JSON.stringify(data.content)
|
|
139
|
+
});
|
|
140
|
+
case 13:
|
|
141
|
+
_context2.next = 16;
|
|
142
|
+
break;
|
|
143
|
+
case 15:
|
|
144
|
+
return _context2.abrupt("return", {
|
|
145
|
+
error: mapBlockError(_context2.t0),
|
|
146
|
+
resourceId: resourceId
|
|
147
|
+
});
|
|
148
|
+
case 16:
|
|
149
|
+
return _context2.abrupt("return", {
|
|
150
|
+
error: stringifyError(_context2.t0),
|
|
151
|
+
resourceId: resourceId
|
|
152
|
+
});
|
|
153
|
+
case 17:
|
|
154
|
+
case "end":
|
|
155
|
+
return _context2.stop();
|
|
156
|
+
}
|
|
157
|
+
}, _callee2, null, [[1, 7]]);
|
|
158
|
+
}));
|
|
159
|
+
function writeData(_x2) {
|
|
160
|
+
return _writeData.apply(this, arguments);
|
|
161
|
+
}
|
|
162
|
+
return writeData;
|
|
163
|
+
}() // soft deletes the source synced block
|
|
164
|
+
}, {
|
|
165
|
+
key: "deleteData",
|
|
166
|
+
value: function () {
|
|
167
|
+
var _deleteData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(resourceId) {
|
|
168
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
169
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
170
|
+
case 0:
|
|
171
|
+
_context3.prev = 0;
|
|
172
|
+
_context3.next = 3;
|
|
173
|
+
return deleteSyncedBlock({
|
|
174
|
+
blockAri: resourceId
|
|
175
|
+
});
|
|
176
|
+
case 3:
|
|
177
|
+
return _context3.abrupt("return", {
|
|
178
|
+
resourceId: resourceId,
|
|
179
|
+
success: true,
|
|
180
|
+
error: undefined
|
|
181
|
+
});
|
|
182
|
+
case 6:
|
|
183
|
+
_context3.prev = 6;
|
|
184
|
+
_context3.t0 = _context3["catch"](0);
|
|
185
|
+
if (!(_context3.t0 instanceof BlockError)) {
|
|
186
|
+
_context3.next = 10;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
return _context3.abrupt("return", {
|
|
190
|
+
resourceId: resourceId,
|
|
191
|
+
success: false,
|
|
192
|
+
error: mapBlockError(_context3.t0)
|
|
193
|
+
});
|
|
194
|
+
case 10:
|
|
195
|
+
return _context3.abrupt("return", {
|
|
196
|
+
resourceId: resourceId,
|
|
197
|
+
success: false,
|
|
198
|
+
error: stringifyError(_context3.t0)
|
|
199
|
+
});
|
|
200
|
+
case 11:
|
|
201
|
+
case "end":
|
|
202
|
+
return _context3.stop();
|
|
203
|
+
}
|
|
204
|
+
}, _callee3, null, [[0, 6]]);
|
|
205
|
+
}));
|
|
206
|
+
function deleteData(_x3) {
|
|
207
|
+
return _deleteData.apply(this, arguments);
|
|
208
|
+
}
|
|
209
|
+
return deleteData;
|
|
210
|
+
}()
|
|
211
|
+
}, {
|
|
212
|
+
key: "generateResourceId",
|
|
213
|
+
value: function generateResourceId(sourceId, localId) {
|
|
214
|
+
return blockResourceIdFromSourceAndLocalId(sourceId, localId);
|
|
215
|
+
}
|
|
216
|
+
}]);
|
|
217
|
+
}();
|
|
218
|
+
/**
|
|
219
|
+
* Factory function to create both providers with shared configuration
|
|
220
|
+
*/
|
|
221
|
+
var createBlockServiceAPIProviders = function createBlockServiceAPIProviders() {
|
|
222
|
+
var fetchProvider = new BlockServiceADFFetchProvider();
|
|
223
|
+
var writeProvider = new BlockServiceADFWriteProvider();
|
|
224
|
+
return {
|
|
225
|
+
fetchProvider: fetchProvider,
|
|
226
|
+
writeProvider: writeProvider
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
export var useMemoizedBlockServiceAPIProviders = function useMemoizedBlockServiceAPIProviders() {
|
|
230
|
+
return useMemo(createBlockServiceAPIProviders, []);
|
|
231
|
+
};
|
|
@@ -6,7 +6,7 @@ import _typeof from "@babel/runtime/helpers/typeof";
|
|
|
6
6
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
8
|
import { SyncBlockError } from '../../common/types';
|
|
9
|
-
import { getLocalIdFromAri, getPageIdAndTypeFromAri } from '../../utils/ari';
|
|
9
|
+
import { getLocalIdFromAri, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from '../../utils/ari';
|
|
10
10
|
import { getContentProperty, createContentProperty, updateContentProperty, deleteContentProperty } from '../../utils/contentProperty';
|
|
11
11
|
import { stringifyError } from '../../utils/errorHandling';
|
|
12
12
|
import { isBlogPageType } from '../../utils/utils';
|
|
@@ -337,6 +337,11 @@ var ConfluenceADFWriteProvider = /*#__PURE__*/function () {
|
|
|
337
337
|
}
|
|
338
338
|
return deleteData;
|
|
339
339
|
}()
|
|
340
|
+
}, {
|
|
341
|
+
key: "generateResourceId",
|
|
342
|
+
value: function generateResourceId(sourceId, localId) {
|
|
343
|
+
return resourceIdFromSourceAndLocalId(sourceId, localId);
|
|
344
|
+
}
|
|
340
345
|
}]);
|
|
341
346
|
}();
|
|
342
347
|
/**
|
|
@@ -170,6 +170,11 @@ export var SyncBlockProvider = /*#__PURE__*/function (_SyncBlockDataProvide) {
|
|
|
170
170
|
}
|
|
171
171
|
return pageARI ? fetchSourceInfo(pageARI, sourceLocalId) : Promise.resolve(undefined);
|
|
172
172
|
}
|
|
173
|
+
}, {
|
|
174
|
+
key: "generateResourceId",
|
|
175
|
+
value: function generateResourceId(sourceId, localId) {
|
|
176
|
+
return this.writeProvider.generateResourceId(sourceId, localId);
|
|
177
|
+
}
|
|
173
178
|
}]);
|
|
174
179
|
}(SyncBlockDataProvider);
|
|
175
180
|
export var useMemoizedSyncedBlockProvider = function useMemoizedSyncedBlockProvider(fetchProvider, writeProvider, sourceId) {
|
|
@@ -6,7 +6,6 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
|
6
6
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
7
7
|
import uuid from 'uuid';
|
|
8
8
|
import { rebaseTransaction as _rebaseTransaction } from '../common/rebase-transaction';
|
|
9
|
-
import { resourceIdFromSourceAndLocalId } from '../utils/ari';
|
|
10
9
|
import { convertSyncBlockPMNodeToSyncBlockData, createBodiedSyncBlockNode as _createBodiedSyncBlockNode } from '../utils/utils';
|
|
11
10
|
export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
12
11
|
function SourceSyncBlockStoreManager(dataProvider) {
|
|
@@ -158,12 +157,10 @@ export var SourceSyncBlockStoreManager = /*#__PURE__*/function () {
|
|
|
158
157
|
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
|
|
159
158
|
var localId = uuid();
|
|
160
159
|
var sourceId = (_this$dataProvider = this.dataProvider) === null || _this$dataProvider === void 0 ? void 0 : _this$dataProvider.getSourceId();
|
|
161
|
-
if (!sourceId) {
|
|
160
|
+
if (!this.dataProvider || !sourceId) {
|
|
162
161
|
throw new Error('Provider of sync block plugin is not set');
|
|
163
162
|
}
|
|
164
|
-
|
|
165
|
-
// This should be generated by the data provider implementation as it differs between data providers
|
|
166
|
-
var resourceId = resourceIdFromSourceAndLocalId(sourceId, localId);
|
|
163
|
+
var resourceId = this.dataProvider.generateResourceId(sourceId, localId);
|
|
167
164
|
return {
|
|
168
165
|
resourceId: resourceId,
|
|
169
166
|
localId: localId
|
package/dist/esm/utils/ari.js
CHANGED
|
@@ -28,9 +28,37 @@ export var getPageARIFromResourceId = function getPageARIFromResourceId(resource
|
|
|
28
28
|
}
|
|
29
29
|
throw new Error("Invalid resourceId: ".concat(resourceId));
|
|
30
30
|
};
|
|
31
|
-
export var getContentPropertyAri = function getContentPropertyAri(contentPropertyId, cloudId) {
|
|
32
|
-
return "ari:cloud:confluence:".concat(cloudId, ":content/").concat(contentPropertyId);
|
|
33
|
-
};
|
|
34
31
|
export var resourceIdFromSourceAndLocalId = function resourceIdFromSourceAndLocalId(sourceId, localId) {
|
|
35
32
|
return sourceId + '/' + localId;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* For the following functions, they are used for the block service API provider.
|
|
37
|
+
* The resourceId/blockResourceId always refers to the block ARI.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param sourceId - the ARI of the document. E.G ari:cloud:confluence:cloudId:page/pageId
|
|
42
|
+
* @param localId - the localId of the block node. A randomly generated UUID
|
|
43
|
+
* @returns the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
|
|
44
|
+
*/
|
|
45
|
+
export var blockResourceIdFromSourceAndLocalId = function blockResourceIdFromSourceAndLocalId(sourceId, localId) {
|
|
46
|
+
var match = sourceId.match(/ari:cloud:confluence:([^:]+):(page|blogpost)\/.*/);
|
|
47
|
+
if (!(match !== null && match !== void 0 && match[1])) {
|
|
48
|
+
throw new Error("Invalid source ARI: ".concat(sourceId));
|
|
49
|
+
}
|
|
50
|
+
var cloudId = match[1];
|
|
51
|
+
return "ari:cloud:blocks:".concat(cloudId, ":synced-block/").concat(localId);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param ari - the block ARI. E.G ari:cloud:blocks:cloudId:synced-block/localId
|
|
56
|
+
* @returns the localId of the block node. A randomly generated UUID
|
|
57
|
+
*/
|
|
58
|
+
export var getLocalIdFromResourceId = function getLocalIdFromResourceId(ari) {
|
|
59
|
+
var match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+\/([a-zA-Z0-9-]+)/);
|
|
60
|
+
if (match !== null && match !== void 0 && match[2]) {
|
|
61
|
+
return match[2];
|
|
62
|
+
}
|
|
63
|
+
throw new Error("Invalid page ARI: ".concat(ari));
|
|
36
64
|
};
|