@atlaskit/editor-synced-block-provider 0.6.1 → 0.8.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.
@@ -1,7 +1,8 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { useMemo } from 'react';
3
- import { getLocalIdFromAri, getPageIdFromAri, resourceIdFromSourceAndLocalId } from '../utils/ari';
3
+ import { getLocalIdFromAri, getPageIdAndTypeFromAri, resourceIdFromSourceAndLocalId } from '../utils/ari';
4
4
  import { getContentProperty, createContentProperty, updateContentProperty } from '../utils/contentProperty';
5
+ import { isBlogPageType } from '../utils/utils';
5
6
 
6
7
  /**
7
8
  * Configuration for Content API providers
@@ -12,17 +13,19 @@ const getContentPropertyKey = (contentPropertyKey, localId) => {
12
13
  };
13
14
  const parseSyncedBlockContentPropertyValue = value => {
14
15
  try {
15
- if (typeof value === 'string') {
16
- return JSON.parse(value);
16
+ if (value !== '') {
17
+ const parsedValue = JSON.parse(value);
18
+ if (parsedValue.content) {
19
+ return parsedValue;
20
+ }
17
21
  }
18
- return value;
19
22
  } catch (error) {
20
23
  // eslint-disable-next-line no-console
21
24
  console.error('Failed to parse synced block content:', error);
22
- return {
23
- content: undefined
24
- };
25
25
  }
26
+ return {
27
+ content: undefined
28
+ };
26
29
  };
27
30
 
28
31
  /**
@@ -33,17 +36,28 @@ class ConfluenceADFFetchProvider {
33
36
  this.config = config;
34
37
  }
35
38
  async fetchData(resourceId) {
36
- var _contentProperty$data, _contentProperty$data2;
37
- const pageId = getPageIdFromAri(resourceId);
39
+ const {
40
+ id: pageId,
41
+ type: pageType
42
+ } = getPageIdAndTypeFromAri(resourceId);
38
43
  const localId = getLocalIdFromAri(resourceId);
39
44
  const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
40
45
  const options = {
41
46
  pageId,
42
47
  key,
43
- cloudId: this.config.cloudId
48
+ cloudId: this.config.cloudId,
49
+ pageType
44
50
  };
45
- const contentProperty = await getContentProperty(options);
46
- const value = (_contentProperty$data = contentProperty.data.confluence.page.properties) === null || _contentProperty$data === void 0 ? void 0 : (_contentProperty$data2 = _contentProperty$data[0]) === null || _contentProperty$data2 === void 0 ? void 0 : _contentProperty$data2.value;
51
+ let value;
52
+ if (isBlogPageType(pageType)) {
53
+ var _contentProperty$data, _contentProperty$data2;
54
+ const contentProperty = await getContentProperty(options);
55
+ value = (_contentProperty$data = contentProperty.data.confluence.blogPost.properties) === null || _contentProperty$data === void 0 ? void 0 : (_contentProperty$data2 = _contentProperty$data[0]) === null || _contentProperty$data2 === void 0 ? void 0 : _contentProperty$data2.value;
56
+ } else {
57
+ var _contentProperty$data3, _contentProperty$data4;
58
+ const contentProperty = await getContentProperty(options);
59
+ value = (_contentProperty$data3 = contentProperty.data.confluence.page.properties) === null || _contentProperty$data3 === void 0 ? void 0 : (_contentProperty$data4 = _contentProperty$data3[0]) === null || _contentProperty$data4 === void 0 ? void 0 : _contentProperty$data4.value;
60
+ }
47
61
  if (!value) {
48
62
  throw new Error('Content property value does not exist');
49
63
  }
@@ -63,24 +77,39 @@ class ConfluenceADFFetchProvider {
63
77
  */
64
78
  class ConfluenceADFWriteProvider {
65
79
  constructor(config) {
66
- _defineProperty(this, "createNewContentProperty", async (pageId, key, value) => {
67
- var _contentProperty$data3;
68
- const contentProperty = await createContentProperty({
80
+ _defineProperty(this, "createNewContentProperty", async (pageId, key, value, pageType) => {
81
+ const options = {
69
82
  pageId,
70
83
  key,
71
84
  value,
72
- cloudId: this.config.cloudId
73
- });
74
- if (((_contentProperty$data3 = contentProperty.data.confluence.createPageProperty.pageProperty) === null || _contentProperty$data3 === void 0 ? void 0 : _contentProperty$data3.key) === key) {
75
- return key;
85
+ cloudId: this.config.cloudId,
86
+ pageType
87
+ };
88
+ if (isBlogPageType(pageType)) {
89
+ var _contentProperty$data5;
90
+ const contentProperty = await createContentProperty(options);
91
+ if (((_contentProperty$data5 = contentProperty.data.confluence.createBlogPostProperty.blogPostProperty) === null || _contentProperty$data5 === void 0 ? void 0 : _contentProperty$data5.key) === key) {
92
+ return key;
93
+ } else {
94
+ throw new Error('Failed to create blog post content property');
95
+ }
76
96
  } else {
77
- throw new Error('Failed to create content property');
97
+ var _contentProperty$data6;
98
+ const contentProperty = await createContentProperty(options);
99
+ if (((_contentProperty$data6 = contentProperty.data.confluence.createPageProperty.pageProperty) === null || _contentProperty$data6 === void 0 ? void 0 : _contentProperty$data6.key) === key) {
100
+ return key;
101
+ } else {
102
+ throw new Error('Failed to create page content property');
103
+ }
78
104
  }
79
105
  });
80
106
  this.config = config;
81
107
  }
82
108
  async writeData(data) {
83
- const pageId = getPageIdFromAri(data.resourceId);
109
+ const {
110
+ id: pageId,
111
+ type: pageType
112
+ } = getPageIdAndTypeFromAri(data.resourceId);
84
113
  if (data.sourceDocumentAri && data.resourceId !== resourceIdFromSourceAndLocalId(data.sourceDocumentAri, data.localId)) {
85
114
  return Promise.reject('Resource ARI differs from source document ARI');
86
115
  }
@@ -88,27 +117,41 @@ class ConfluenceADFWriteProvider {
88
117
  content: data.content
89
118
  });
90
119
  if (data.resourceId) {
91
- var _contentProperty$data4;
92
120
  // Update existing content property
93
121
  const localId = getLocalIdFromAri(data.resourceId);
94
122
  const key = getContentPropertyKey(this.config.contentPropertyKey, localId);
95
- const contentProperty = await updateContentProperty({
123
+ const options = {
96
124
  pageId,
97
125
  key,
98
126
  value: syncedBlockValue,
99
- cloudId: this.config.cloudId
100
- });
101
- if (((_contentProperty$data4 = contentProperty.data.confluence.updateValuePageProperty.pageProperty) === null || _contentProperty$data4 === void 0 ? void 0 : _contentProperty$data4.key) === key) {
102
- return key;
103
- } else if (contentProperty.data.confluence.updateValuePageProperty.pageProperty === null) {
104
- return this.createNewContentProperty(pageId, key, syncedBlockValue);
127
+ cloudId: this.config.cloudId,
128
+ pageType
129
+ };
130
+ if (isBlogPageType(pageType)) {
131
+ var _contentProperty$data7;
132
+ const contentProperty = await updateContentProperty(options);
133
+ if (((_contentProperty$data7 = contentProperty.data.confluence.updateValueBlogPostProperty.blogPostProperty) === null || _contentProperty$data7 === void 0 ? void 0 : _contentProperty$data7.key) === key) {
134
+ return key;
135
+ } else if (contentProperty.data.confluence.updateValueBlogPostProperty.blogPostProperty === null) {
136
+ return this.createNewContentProperty(pageId, key, syncedBlockValue, pageType);
137
+ } else {
138
+ throw new Error('Failed to update blog post content property');
139
+ }
105
140
  } else {
106
- throw new Error('Failed to update content property');
141
+ var _contentProperty$data8;
142
+ const contentProperty = await updateContentProperty(options);
143
+ if (((_contentProperty$data8 = contentProperty.data.confluence.updateValuePageProperty.pageProperty) === null || _contentProperty$data8 === void 0 ? void 0 : _contentProperty$data8.key) === key) {
144
+ return key;
145
+ } else if (contentProperty.data.confluence.updateValuePageProperty.pageProperty === null) {
146
+ return this.createNewContentProperty(pageId, key, syncedBlockValue, pageType);
147
+ } else {
148
+ throw new Error('Failed to update content property');
149
+ }
107
150
  }
108
151
  } else {
109
152
  // Create new content property
110
153
  const key = getContentPropertyKey(this.config.contentPropertyKey, data.localId);
111
- return this.createNewContentProperty(pageId, key, syncedBlockValue);
154
+ return this.createNewContentProperty(pageId, key, syncedBlockValue, pageType);
112
155
  }
113
156
  }
114
157
  }
@@ -1,37 +1,40 @@
1
- export const getConfluencePageAri = (pageId, cloudId) => `ari:cloud:confluence:${cloudId}:page/${pageId}`;
2
- export const getPageIdFromAri = ari => {
3
- // eslint-disable-next-line require-unicode-regexp
4
- const match = ari.match(/ari:cloud:confluence:[^:]+:page\/(\d+)/);
5
- if (match !== null && match !== void 0 && match[1]) {
6
- return match[1];
1
+ /* eslint-disable require-unicode-regexp */
2
+
3
+ export const getConfluencePageAri = (pageId, cloudId, pageType = 'page') => `ari:cloud:confluence:${cloudId}:${pageType}/${pageId}`;
4
+ export const getPageIdAndTypeFromAri = ari => {
5
+ const match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/(\d+)/);
6
+ if (match !== null && match !== void 0 && match[2]) {
7
+ return {
8
+ type: match[1],
9
+ id: match[2]
10
+ };
7
11
  }
8
12
  throw new Error(`Invalid page ARI: ${ari}`);
9
13
  };
10
-
11
- /**
12
- *
13
- * @param ari ari:cloud:confluence:<cloudId>:page/<pageId>/<localId>
14
- * @returns
15
- */
16
14
  export const getLocalIdFromAri = ari => {
17
- // eslint-disable-next-line require-unicode-regexp
18
- const match = ari.match(/ari:cloud:confluence:[^:]+:page\/\d+\/([a-zA-Z0-9-]+)/);
19
- if (match !== null && match !== void 0 && match[1]) {
20
- return match[1];
15
+ const match = ari.match(/ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+\/([a-zA-Z0-9-]+)/);
16
+ if (match !== null && match !== void 0 && match[2]) {
17
+ return match[2];
21
18
  }
22
19
  throw new Error(`Invalid page ARI: ${ari}`);
23
20
  };
24
21
  export const getPageARIFromResourceId = resourceId => {
25
- // eslint-disable-next-line require-unicode-regexp
26
- const match = resourceId.match(/(ari:cloud:confluence:[^:]+:page\/\d+)\/([a-zA-Z0-9-]+)$/);
22
+ const match = resourceId.match(/(ari:cloud:confluence:[^:]+:(page|blogpost)\/\d+)\/([a-zA-Z0-9-]+)$/);
27
23
  if (match !== null && match !== void 0 && match[1]) {
28
24
  return match[1];
29
25
  }
30
26
  throw new Error(`Invalid resourceId: ${resourceId}`);
31
27
  };
32
28
  export const getContentPropertyAri = (contentPropertyId, cloudId) => `ari:cloud:confluence:${cloudId}:content/${contentPropertyId}`;
29
+
30
+ /**
31
+ * DEPRECATED - Will be removed in the future
32
+ * @private
33
+ * @deprecated
34
+ * @param ari
35
+ * @returns
36
+ */
33
37
  export const getContentPropertyIdFromAri = ari => {
34
- // eslint-disable-next-line require-unicode-regexp
35
38
  const match = ari.match(/ari:cloud:confluence:[^:]+:content\/([^/]+)/);
36
39
  if (match) {
37
40
  return match[1];
@@ -1,4 +1,5 @@
1
1
  import { getConfluencePageAri } from './ari';
2
+ import { isBlogPageType } from './utils';
2
3
  const COMMON_HEADERS = {
3
4
  'Content-Type': 'application/json',
4
5
  Accept: 'application/json'
@@ -16,7 +17,7 @@ const UPDATE_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_UPDATE';
16
17
  * @param key
17
18
  * @returns
18
19
  */
19
- const GET_QUERY = `query ${GET_OPERATION_NAME} ($id: ID!, $keys: [String]!) {
20
+ const GET_PAGE_QUERY = `query ${GET_OPERATION_NAME} ($id: ID!, $keys: [String]!) {
20
21
  confluence {
21
22
  page (id: $id) {
22
23
  properties(keys: $keys) {
@@ -27,6 +28,23 @@ const GET_QUERY = `query ${GET_OPERATION_NAME} ($id: ID!, $keys: [String]!) {
27
28
  }
28
29
  }`;
29
30
 
31
+ /**
32
+ * Query to get the blog page property by key
33
+ * @param documentARI
34
+ * @param key
35
+ * @returns
36
+ */
37
+ const GET_BLOG_QUERY = `query ${GET_OPERATION_NAME} ($id: ID!, $keys: [String]!) {
38
+ confluence {
39
+ blogPost (id: $id) {
40
+ properties(keys: $keys) {
41
+ key,
42
+ value
43
+ }
44
+ }
45
+ }
46
+ }`;
47
+
30
48
  /**
31
49
  * Query to create a page property with key and value
32
50
  * @param documentARI
@@ -34,7 +52,7 @@ const GET_QUERY = `query ${GET_OPERATION_NAME} ($id: ID!, $keys: [String]!) {
34
52
  * @param value
35
53
  * @returns
36
54
  */
37
- const CREATE_QUERY = `mutation ${CREATE_OPERATION_NAME} ($input: ConfluenceCreatePagePropertyInput!){
55
+ const CREATE_PAGE_QUERY = `mutation ${CREATE_OPERATION_NAME} ($input: ConfluenceCreatePagePropertyInput!){
38
56
  confluence {
39
57
  createPageProperty(input: $input) {
40
58
  pageProperty {
@@ -45,6 +63,24 @@ const CREATE_QUERY = `mutation ${CREATE_OPERATION_NAME} ($input: ConfluenceCreat
45
63
  }
46
64
  }`;
47
65
 
66
+ /**
67
+ * Query to create a blog page property with key and value
68
+ * @param documentARI
69
+ * @param key
70
+ * @param value
71
+ * @returns
72
+ */
73
+ const CREATE_BLOG_QUERY = `mutation ${CREATE_OPERATION_NAME} ($input: ConfluenceCreateBlogPostPropertyInput!){
74
+ confluence {
75
+ createBlogPostProperty(input: $input) {
76
+ blogPostProperty {
77
+ key,
78
+ value
79
+ }
80
+ }
81
+ }
82
+ }`;
83
+
48
84
  /**
49
85
  * Query to update a page property with key and value without bumping the version
50
86
  * @param documentARI
@@ -52,7 +88,7 @@ const CREATE_QUERY = `mutation ${CREATE_OPERATION_NAME} ($input: ConfluenceCreat
52
88
  * @param value
53
89
  * @returns
54
90
  */
55
- const UPDATE_QUERY = `mutation ${UPDATE_OPERATION_NAME} ($input: ConfluenceUpdateValuePagePropertyInput!) {
91
+ const UPDATE_PAGE_QUERY = `mutation ${UPDATE_OPERATION_NAME} ($input: ConfluenceUpdateValuePagePropertyInput!) {
56
92
  confluence {
57
93
  updateValuePageProperty(input: $input) {
58
94
  pageProperty {
@@ -62,14 +98,34 @@ const UPDATE_QUERY = `mutation ${UPDATE_OPERATION_NAME} ($input: ConfluenceUpdat
62
98
  }
63
99
  }
64
100
  }`;
101
+
102
+ /**
103
+ * Query to update a blog page property with key and value without bumping the version
104
+ * @param documentARI
105
+ * @param key
106
+ * @param value
107
+ * @returns
108
+ */
109
+ const UPDATE_BLOG_QUERY = `mutation ${UPDATE_OPERATION_NAME} ($input: ConfluenceUpdateValueBlogPostPropertyInput!) {
110
+ confluence {
111
+ updateValueBlogPostProperty(input: $input) {
112
+ blogPostProperty {
113
+ key,
114
+ value
115
+ }
116
+ }
117
+ }
118
+ }`;
65
119
  export const getContentProperty = async ({
66
120
  pageId,
67
121
  key,
68
- cloudId
122
+ cloudId,
123
+ pageType
69
124
  }) => {
70
- const documentARI = getConfluencePageAri(pageId, cloudId);
125
+ const documentARI = getConfluencePageAri(pageId, cloudId, pageType);
126
+ const isBlog = isBlogPageType(pageType);
71
127
  const bodyData = {
72
- query: GET_QUERY,
128
+ query: isBlog ? GET_BLOG_QUERY : GET_PAGE_QUERY,
73
129
  operationName: GET_OPERATION_NAME,
74
130
  variables: {
75
131
  id: documentARI,
@@ -87,26 +143,42 @@ export const getContentProperty = async ({
87
143
  if (!response.ok) {
88
144
  throw new Error(`Failed to get content property: ${response.statusText}`);
89
145
  }
90
- const contentProperty = await response.json();
91
- return contentProperty;
146
+ return await response.json();
92
147
  };
93
148
  export const updateContentProperty = async ({
94
149
  pageId,
95
150
  key,
96
151
  value,
97
- cloudId
152
+ cloudId,
153
+ pageType
98
154
  }) => {
99
- const documentARI = getConfluencePageAri(pageId, cloudId);
155
+ const documentARI = getConfluencePageAri(pageId, cloudId, pageType);
156
+ const isBlog = isBlogPageType(pageType);
157
+ const useSameVersion = {
158
+ useSameVersion: true
159
+ };
160
+ let input = {
161
+ ...(isBlog ? {
162
+ blogPostId: documentARI
163
+ } : {
164
+ pageId: documentARI
165
+ }),
166
+ key,
167
+ value
168
+ };
169
+
170
+ // Blog content properties don't support the useSameVersion flag at the moment
171
+ if (!isBlog) {
172
+ input = {
173
+ ...input,
174
+ ...useSameVersion
175
+ };
176
+ }
100
177
  const bodyData = {
101
- query: UPDATE_QUERY,
178
+ query: isBlog ? UPDATE_BLOG_QUERY : UPDATE_PAGE_QUERY,
102
179
  operationName: UPDATE_OPERATION_NAME,
103
180
  variables: {
104
- input: {
105
- pageId: documentARI,
106
- key,
107
- value,
108
- useSameVersion: true
109
- }
181
+ input
110
182
  }
111
183
  };
112
184
  const response = await fetch(GRAPHQL_ENDPOINT, {
@@ -120,25 +192,30 @@ export const updateContentProperty = async ({
120
192
  if (!response.ok) {
121
193
  throw new Error(`Failed to update content property: ${response.statusText}`);
122
194
  }
123
- const contentProperty = await response.json();
124
- return contentProperty;
195
+ return await response.json();
125
196
  };
126
197
  export const createContentProperty = async ({
127
198
  pageId,
128
199
  key,
129
200
  value,
130
- cloudId
201
+ cloudId,
202
+ pageType
131
203
  }) => {
132
- const documentARI = getConfluencePageAri(pageId, cloudId);
204
+ const documentARI = getConfluencePageAri(pageId, cloudId, pageType);
205
+ const isBlog = isBlogPageType(pageType);
133
206
 
134
207
  // eslint-disable-next-line require-unicode-regexp
135
208
  const escapedValue = value.replace(/"/g, '\\"');
136
209
  const bodyData = {
137
- query: CREATE_QUERY,
210
+ query: isBlog ? CREATE_BLOG_QUERY : CREATE_PAGE_QUERY,
138
211
  operationName: CREATE_OPERATION_NAME,
139
212
  variables: {
140
213
  input: {
141
- pageId: documentARI,
214
+ ...(isBlog ? {
215
+ blogPostId: documentARI
216
+ } : {
217
+ pageId: documentARI
218
+ }),
142
219
  key,
143
220
  value: escapedValue
144
221
  }
@@ -155,6 +232,5 @@ export const createContentProperty = async ({
155
232
  if (!response.ok) {
156
233
  throw new Error(`Failed to create content property: ${response.statusText}`);
157
234
  }
158
- const contentProperty = await response.json();
159
- return contentProperty;
235
+ return await response.json();
160
236
  };
@@ -10,4 +10,7 @@ export const convertSyncBlockPMNodeToSyncBlockData = (node, includeContent = fal
10
10
  },
11
11
  content: includeContent ? node.content.content.map(toJSON) : undefined
12
12
  };
13
+ };
14
+ export const isBlogPageType = pageType => {
15
+ return pageType === 'blogpost';
13
16
  };