@atlaskit/editor-synced-block-provider 13.0.0 → 13.1.1

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaskit/editor-synced-block-provider
2
2
 
3
+ ## 13.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 13.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`cf59769ca5527`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cf59769ca5527) -
14
+ Export `getJiraIssueAriFromSourceAri` and rewrite Jira `issuefieldvalue` source ARIs to the parent
15
+ issue ARI before AGG `issueById`, object-resolver, and media token requests. Returned metadata
16
+ keeps the original field-value `sourceAri`. Gated by `editor_synced_blocks_jira_custom_rich_text`.
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+
3
22
  ## 13.0.0
4
23
 
5
24
  ### Patch Changes
@@ -3,10 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getJiraWorkItemIdFromAri = exports.getJiraWorkItemAri = void 0;
6
+ exports.getJiraWorkItemIdFromAri = exports.getJiraWorkItemAri = exports.getJiraIssueAriFromSourceAri = void 0;
7
7
  /* eslint-disable require-unicode-regexp */
8
8
 
9
9
  var JIRA_WORK_ITEM_ARI_REGEX = /ari:cloud:jira:([^:]+):issue\/(\d+)/;
10
+ var JIRA_ISSUE_FIELD_VALUE_ARI_REGEX = /ari:cloud:jira:([^:]+):issuefieldvalue\/([^/]+)\/([^/]+)/;
10
11
 
11
12
  /**
12
13
  * Generates the Jira work item ARI
@@ -19,10 +20,23 @@ var getJiraWorkItemAri = exports.getJiraWorkItemAri = function getJiraWorkItemAr
19
20
  workItemId = _ref.workItemId;
20
21
  return "ari:cloud:jira:".concat(cloudId, ":issue/").concat(workItemId);
21
22
  };
23
+ var getFieldValueAriParts = function getFieldValueAriParts(ari) {
24
+ var match = ari.match(JIRA_ISSUE_FIELD_VALUE_ARI_REGEX);
25
+ if (match !== null && match !== void 0 && match[1] && match[2] && match[3]) {
26
+ return {
27
+ cloudId: match[1],
28
+ issueId: match[2],
29
+ fieldId: match[3]
30
+ };
31
+ }
32
+ return undefined;
33
+ };
22
34
 
23
35
  /**
24
- * Extracts the Jira work item ID from the Jira work item ARI
25
- * @param ari - the Jira work item ARI
36
+ * Extracts the Jira work item ID from an issue ARI or a field-value source ARI.
37
+ * Field identity stays on `sourceAri`; callers that need an issue id for AGG
38
+ * or media must not read `fieldId` from `blockAri`.
39
+ * @param ari - the Jira issue or issuefieldvalue ARI
26
40
  * @returns the Jira work item ID
27
41
  */
28
42
  var getJiraWorkItemIdFromAri = exports.getJiraWorkItemIdFromAri = function getJiraWorkItemIdFromAri(_ref2) {
@@ -31,5 +45,26 @@ var getJiraWorkItemIdFromAri = exports.getJiraWorkItemIdFromAri = function getJi
31
45
  if (match !== null && match !== void 0 && match[2]) {
32
46
  return match[2];
33
47
  }
48
+ var fieldValueParts = getFieldValueAriParts(ari);
49
+ if (fieldValueParts) {
50
+ return fieldValueParts.issueId;
51
+ }
34
52
  throw new Error("Invalid Jira work item ARI: ".concat(ari));
53
+ };
54
+
55
+ /**
56
+ * Rewrites a Jira field-value source ARI to the parent issue ARI used by AGG
57
+ * (`issueById`, media tokens, object-resolver). All other ARIs, including
58
+ * issue ARIs and unrecognized Media context ids, are returned as-is.
59
+ */
60
+ var getJiraIssueAriFromSourceAri = exports.getJiraIssueAriFromSourceAri = function getJiraIssueAriFromSourceAri(_ref3) {
61
+ var ari = _ref3.ari;
62
+ var fieldValueParts = getFieldValueAriParts(ari);
63
+ if (fieldValueParts) {
64
+ return getJiraWorkItemAri({
65
+ cloudId: fieldValueParts.cloudId,
66
+ workItemId: fieldValueParts.issueId
67
+ });
68
+ }
69
+ return ari;
35
70
  };
@@ -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 _retry = require("../../utils/retry");
13
+ var _ari = require("./ari");
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; }
14
15
  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) { (0, _defineProperty2.default)(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; }
15
16
  var COMMON_HEADERS = {
@@ -70,16 +71,19 @@ var getJiraMediaReadToken = /*#__PURE__*/function () {
70
71
  * Fetches a media read token for a Jira issue, to allow media uploaded to Jira
71
72
  * to be rendered in cross-product synced block references (e.g. in Confluence).
72
73
  *
73
- * @param issueAri - the Jira issue ARI (e.g. ari:cloud:jira:{cloudId}:issue/{issueId})
74
+ * @param sourceAri - the Jira issue ARI or field-value source ARI
74
75
  * @returns TokenData with token, config (clientId + fileStoreUrl), and optional collectionId
75
76
  */
76
77
  var fetchJiraMediaToken = exports.fetchJiraMediaToken = /*#__PURE__*/function () {
77
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(issueAri) {
78
- var _response$data, _mediaReadToken$token, _mediaReadToken$token2, response, mediaReadToken, clientId, endpointUrl, token, errorMsg, _t;
78
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(sourceAri) {
79
+ var _response$data, _mediaReadToken$token, _mediaReadToken$token2, issueAri, response, mediaReadToken, clientId, endpointUrl, token, errorMsg, _t;
79
80
  return _regenerator.default.wrap(function (_context2) {
80
81
  while (1) switch (_context2.prev = _context2.next) {
81
82
  case 0:
82
83
  _context2.prev = 0;
84
+ issueAri = (0, _ari.getJiraIssueAriFromSourceAri)({
85
+ ari: sourceAri
86
+ });
83
87
  _context2.next = 1;
84
88
  return getJiraMediaReadToken(issueAri);
85
89
  case 1:
@@ -9,6 +9,7 @@ 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
11
  var _retry = require("../../utils/retry");
12
+ var _ari = require("./ari");
12
13
  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; }
13
14
  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) { (0, _defineProperty2.default)(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; } /* eslint-disable require-unicode-regexp */
14
15
  var COMMON_HEADERS = {
@@ -29,7 +30,7 @@ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
29
30
  // SyncedLocationDropdown can render the correct ADS issue-type icon.
30
31
  var GET_SOURCE_INFO_QUERY = "query ".concat(GET_SOURCE_INFO_OPERATION_NAME, " ($id: ID!) {\n jira {\n\tissueById(id: $id) {\n\tid\n\twebUrl\n\tsummary\n\tissueType {\n\t\tname\n\t\tavatar {\n\t\txsmall\n\t\t}\n\t}\n\t}\n }}");
31
32
  var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
32
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(ari) {
33
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(issueAri) {
33
34
  var bodyData, response;
34
35
  return _regenerator.default.wrap(function (_context) {
35
36
  while (1) switch (_context.prev = _context.next) {
@@ -38,7 +39,7 @@ var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
38
39
  query: GET_SOURCE_INFO_QUERY,
39
40
  operationName: GET_SOURCE_INFO_OPERATION_NAME,
40
41
  variables: {
41
- id: ari
42
+ id: issueAri
42
43
  }
43
44
  };
44
45
  _context.next = 1;
@@ -70,7 +71,7 @@ var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
70
71
  };
71
72
  }();
72
73
  var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
73
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(ari) {
74
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(sourceAri, issueAri) {
74
75
  var response, _payload$data, _payload$data2, payload, url, title;
75
76
  return _regenerator.default.wrap(function (_context2) {
76
77
  while (1) switch (_context2.prev = _context2.next) {
@@ -83,7 +84,7 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
83
84
  Accept: 'application/json'
84
85
  },
85
86
  body: JSON.stringify({
86
- ari: ari
87
+ ari: issueAri
87
88
  })
88
89
  });
89
90
  case 1:
@@ -101,7 +102,7 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
101
102
  return _context2.abrupt("return", {
102
103
  url: typeof url === 'string' ? url : undefined,
103
104
  title: typeof title === 'string' ? title : undefined,
104
- sourceAri: ari
105
+ sourceAri: sourceAri
105
106
  });
106
107
  case 3:
107
108
  throw new Error("Failed to resolve ari: ".concat(response.statusText));
@@ -111,7 +112,7 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
111
112
  }
112
113
  }, _callee2);
113
114
  }));
114
- return function resolveNoAccessWorkItemInfo(_x2) {
115
+ return function resolveNoAccessWorkItemInfo(_x2, _x3) {
115
116
  return _ref2.apply(this, arguments);
116
117
  };
117
118
  }();
@@ -138,16 +139,21 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
138
139
  */
139
140
  var fetchJiraWorkItemInfo = exports.fetchJiraWorkItemInfo = /*#__PURE__*/function () {
140
141
  var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(workItemAri, hasAccess) {
141
- var _response$data, _contentData$issueTyp, _contentData$issueTyp2, response, contentData, webUrl, summary, issueTypeName, issueType;
142
+ var issueAri, _response$data, _contentData$issueTyp, _contentData$issueTyp2, response, contentData, webUrl, summary, issueTypeName, issueType;
142
143
  return _regenerator.default.wrap(function (_context3) {
143
144
  while (1) switch (_context3.prev = _context3.next) {
144
145
  case 0:
146
+ // AGG `issueById` and object-resolver only understand issue ARIs. Field-value
147
+ // source ARIs keep their original identity on the returned `sourceAri`.
148
+ issueAri = (0, _ari.getJiraIssueAriFromSourceAri)({
149
+ ari: workItemAri
150
+ });
145
151
  if (!hasAccess) {
146
152
  _context3.next = 2;
147
153
  break;
148
154
  }
149
155
  _context3.next = 1;
150
- return getJiraWorkItemSourceInfo(workItemAri);
156
+ return getJiraWorkItemSourceInfo(issueAri);
151
157
  case 1:
152
158
  response = _context3.sent;
153
159
  contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.jira) === null || _response$data === void 0 ? void 0 : _response$data.issueById;
@@ -168,7 +174,7 @@ var fetchJiraWorkItemInfo = exports.fetchJiraWorkItemInfo = /*#__PURE__*/functio
168
174
  }));
169
175
  case 2:
170
176
  _context3.next = 3;
171
- return resolveNoAccessWorkItemInfo(workItemAri);
177
+ return resolveNoAccessWorkItemInfo(workItemAri, issueAri);
172
178
  case 3:
173
179
  return _context3.abrupt("return", _context3.sent);
174
180
  case 4:
@@ -177,7 +183,7 @@ var fetchJiraWorkItemInfo = exports.fetchJiraWorkItemInfo = /*#__PURE__*/functio
177
183
  }
178
184
  }, _callee3);
179
185
  }));
180
- return function fetchJiraWorkItemInfo(_x3, _x4) {
186
+ return function fetchJiraWorkItemInfo(_x4, _x5) {
181
187
  return _ref3.apply(this, arguments);
182
188
  };
183
189
  }();
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "getJiraIssueAriFromSourceAri", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _ari.getJiraIssueAriFromSourceAri;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "getJiraWorkItemAri", {
7
13
  enumerable: true,
8
14
  get: function get() {
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable require-unicode-regexp */
2
2
 
3
3
  const JIRA_WORK_ITEM_ARI_REGEX = /ari:cloud:jira:([^:]+):issue\/(\d+)/;
4
+ const JIRA_ISSUE_FIELD_VALUE_ARI_REGEX = /ari:cloud:jira:([^:]+):issuefieldvalue\/([^/]+)\/([^/]+)/;
4
5
 
5
6
  /**
6
7
  * Generates the Jira work item ARI
@@ -14,10 +15,23 @@ export const getJiraWorkItemAri = ({
14
15
  }) => {
15
16
  return `ari:cloud:jira:${cloudId}:issue/${workItemId}`;
16
17
  };
18
+ const getFieldValueAriParts = ari => {
19
+ const match = ari.match(JIRA_ISSUE_FIELD_VALUE_ARI_REGEX);
20
+ if (match !== null && match !== void 0 && match[1] && match[2] && match[3]) {
21
+ return {
22
+ cloudId: match[1],
23
+ issueId: match[2],
24
+ fieldId: match[3]
25
+ };
26
+ }
27
+ return undefined;
28
+ };
17
29
 
18
30
  /**
19
- * Extracts the Jira work item ID from the Jira work item ARI
20
- * @param ari - the Jira work item ARI
31
+ * Extracts the Jira work item ID from an issue ARI or a field-value source ARI.
32
+ * Field identity stays on `sourceAri`; callers that need an issue id for AGG
33
+ * or media must not read `fieldId` from `blockAri`.
34
+ * @param ari - the Jira issue or issuefieldvalue ARI
21
35
  * @returns the Jira work item ID
22
36
  */
23
37
  export const getJiraWorkItemIdFromAri = ({
@@ -27,5 +41,27 @@ export const getJiraWorkItemIdFromAri = ({
27
41
  if (match !== null && match !== void 0 && match[2]) {
28
42
  return match[2];
29
43
  }
44
+ const fieldValueParts = getFieldValueAriParts(ari);
45
+ if (fieldValueParts) {
46
+ return fieldValueParts.issueId;
47
+ }
30
48
  throw new Error(`Invalid Jira work item ARI: ${ari}`);
49
+ };
50
+
51
+ /**
52
+ * Rewrites a Jira field-value source ARI to the parent issue ARI used by AGG
53
+ * (`issueById`, media tokens, object-resolver). All other ARIs, including
54
+ * issue ARIs and unrecognized Media context ids, are returned as-is.
55
+ */
56
+ export const getJiraIssueAriFromSourceAri = ({
57
+ ari
58
+ }) => {
59
+ const fieldValueParts = getFieldValueAriParts(ari);
60
+ if (fieldValueParts) {
61
+ return getJiraWorkItemAri({
62
+ cloudId: fieldValueParts.cloudId,
63
+ workItemId: fieldValueParts.issueId
64
+ });
65
+ }
66
+ return ari;
31
67
  };
@@ -1,5 +1,6 @@
1
1
  import { logException } from '@atlaskit/editor-common/monitoring';
2
2
  import { fetchWithRetry } from '../../utils/retry';
3
+ import { getJiraIssueAriFromSourceAri } from './ari';
3
4
  const COMMON_HEADERS = {
4
5
  'Content-Type': 'application/json',
5
6
  Accept: 'application/json'
@@ -55,12 +56,15 @@ const getJiraMediaReadToken = async issueAri => {
55
56
  * Fetches a media read token for a Jira issue, to allow media uploaded to Jira
56
57
  * to be rendered in cross-product synced block references (e.g. in Confluence).
57
58
  *
58
- * @param issueAri - the Jira issue ARI (e.g. ari:cloud:jira:{cloudId}:issue/{issueId})
59
+ * @param sourceAri - the Jira issue ARI or field-value source ARI
59
60
  * @returns TokenData with token, config (clientId + fileStoreUrl), and optional collectionId
60
61
  */
61
- export const fetchJiraMediaToken = async issueAri => {
62
+ export const fetchJiraMediaToken = async sourceAri => {
62
63
  try {
63
64
  var _response$data, _response$data$jira, _response$data$jira$i, _mediaReadToken$token, _mediaReadToken$token2, _mediaReadToken$token3, _mediaReadToken$token4, _mediaReadToken$token5;
65
+ const issueAri = getJiraIssueAriFromSourceAri({
66
+ ari: sourceAri
67
+ });
64
68
  const response = await getJiraMediaReadToken(issueAri);
65
69
  const mediaReadToken = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$jira = _response$data.jira) === null || _response$data$jira === void 0 ? void 0 : (_response$data$jira$i = _response$data$jira.issueById) === null || _response$data$jira$i === void 0 ? void 0 : _response$data$jira$i.mediaReadToken;
66
70
  const clientId = mediaReadToken === null || mediaReadToken === void 0 ? void 0 : mediaReadToken.clientId;
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable require-unicode-regexp */
2
2
 
3
3
  import { fetchWithRetry } from '../../utils/retry';
4
+ import { getJiraIssueAriFromSourceAri } from './ari';
4
5
  const COMMON_HEADERS = {
5
6
  'Content-Type': 'application/json',
6
7
  Accept: 'application/json'
@@ -31,12 +32,12 @@ const GET_SOURCE_INFO_QUERY = `query ${GET_SOURCE_INFO_OPERATION_NAME} ($id: ID!
31
32
  }
32
33
  }
33
34
  }}`;
34
- const getJiraWorkItemSourceInfo = async ari => {
35
+ const getJiraWorkItemSourceInfo = async issueAri => {
35
36
  const bodyData = {
36
37
  query: GET_SOURCE_INFO_QUERY,
37
38
  operationName: GET_SOURCE_INFO_OPERATION_NAME,
38
39
  variables: {
39
- id: ari
40
+ id: issueAri
40
41
  }
41
42
  };
42
43
  const response = await fetchWithRetry(GRAPHQL_ENDPOINT, {
@@ -52,7 +53,7 @@ const getJiraWorkItemSourceInfo = async ari => {
52
53
  }
53
54
  return await response.json();
54
55
  };
55
- const resolveNoAccessWorkItemInfo = async ari => {
56
+ const resolveNoAccessWorkItemInfo = async (sourceAri, issueAri) => {
56
57
  const response = await fetch('/gateway/api/object-resolver/resolve/ari', {
57
58
  method: 'POST',
58
59
  headers: {
@@ -60,7 +61,7 @@ const resolveNoAccessWorkItemInfo = async ari => {
60
61
  Accept: 'application/json'
61
62
  },
62
63
  body: JSON.stringify({
63
- ari
64
+ ari: issueAri
64
65
  })
65
66
  });
66
67
  if (response.ok) {
@@ -71,7 +72,7 @@ const resolveNoAccessWorkItemInfo = async ari => {
71
72
  return {
72
73
  url: typeof url === 'string' ? url : undefined,
73
74
  title: typeof title === 'string' ? title : undefined,
74
- sourceAri: ari
75
+ sourceAri
75
76
  };
76
77
  } else {
77
78
  throw new Error(`Failed to resolve ari: ${response.statusText}`);
@@ -99,9 +100,14 @@ const resolveNoAccessWorkItemInfo = async ari => {
99
100
  * the separate `issueType` field returned alongside `summary` / `webUrl`.
100
101
  */
101
102
  export const fetchJiraWorkItemInfo = async (workItemAri, hasAccess) => {
103
+ // AGG `issueById` and object-resolver only understand issue ARIs. Field-value
104
+ // source ARIs keep their original identity on the returned `sourceAri`.
105
+ const issueAri = getJiraIssueAriFromSourceAri({
106
+ ari: workItemAri
107
+ });
102
108
  if (hasAccess) {
103
109
  var _response$data, _response$data$jira, _contentData$issueTyp, _contentData$issueTyp2, _contentData$issueTyp3;
104
- const response = await getJiraWorkItemSourceInfo(workItemAri);
110
+ const response = await getJiraWorkItemSourceInfo(issueAri);
105
111
  const contentData = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$jira = _response$data.jira) === null || _response$data$jira === void 0 ? void 0 : _response$data$jira.issueById;
106
112
  const webUrl = typeof (contentData === null || contentData === void 0 ? void 0 : contentData.webUrl) === 'string' ? contentData.webUrl : undefined;
107
113
  const summary = typeof (contentData === null || contentData === void 0 ? void 0 : contentData.summary) === 'string' ? contentData.summary : undefined;
@@ -121,6 +127,6 @@ export const fetchJiraWorkItemInfo = async (workItemAri, hasAccess) => {
121
127
  issueType
122
128
  });
123
129
  } else {
124
- return await resolveNoAccessWorkItemInfo(workItemAri);
130
+ return await resolveNoAccessWorkItemInfo(workItemAri, issueAri);
125
131
  }
126
132
  };
@@ -1,2 +1,2 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
- export { getJiraWorkItemAri, getJiraWorkItemIdFromAri } from '../clients/jira/ari';
2
+ export { getJiraIssueAriFromSourceAri, getJiraWorkItemAri, getJiraWorkItemIdFromAri } from '../clients/jira/ari';
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable require-unicode-regexp */
2
2
 
3
3
  var JIRA_WORK_ITEM_ARI_REGEX = /ari:cloud:jira:([^:]+):issue\/(\d+)/;
4
+ var JIRA_ISSUE_FIELD_VALUE_ARI_REGEX = /ari:cloud:jira:([^:]+):issuefieldvalue\/([^/]+)\/([^/]+)/;
4
5
 
5
6
  /**
6
7
  * Generates the Jira work item ARI
@@ -13,10 +14,23 @@ export var getJiraWorkItemAri = function getJiraWorkItemAri(_ref) {
13
14
  workItemId = _ref.workItemId;
14
15
  return "ari:cloud:jira:".concat(cloudId, ":issue/").concat(workItemId);
15
16
  };
17
+ var getFieldValueAriParts = function getFieldValueAriParts(ari) {
18
+ var match = ari.match(JIRA_ISSUE_FIELD_VALUE_ARI_REGEX);
19
+ if (match !== null && match !== void 0 && match[1] && match[2] && match[3]) {
20
+ return {
21
+ cloudId: match[1],
22
+ issueId: match[2],
23
+ fieldId: match[3]
24
+ };
25
+ }
26
+ return undefined;
27
+ };
16
28
 
17
29
  /**
18
- * Extracts the Jira work item ID from the Jira work item ARI
19
- * @param ari - the Jira work item ARI
30
+ * Extracts the Jira work item ID from an issue ARI or a field-value source ARI.
31
+ * Field identity stays on `sourceAri`; callers that need an issue id for AGG
32
+ * or media must not read `fieldId` from `blockAri`.
33
+ * @param ari - the Jira issue or issuefieldvalue ARI
20
34
  * @returns the Jira work item ID
21
35
  */
22
36
  export var getJiraWorkItemIdFromAri = function getJiraWorkItemIdFromAri(_ref2) {
@@ -25,5 +39,26 @@ export var getJiraWorkItemIdFromAri = function getJiraWorkItemIdFromAri(_ref2) {
25
39
  if (match !== null && match !== void 0 && match[2]) {
26
40
  return match[2];
27
41
  }
42
+ var fieldValueParts = getFieldValueAriParts(ari);
43
+ if (fieldValueParts) {
44
+ return fieldValueParts.issueId;
45
+ }
28
46
  throw new Error("Invalid Jira work item ARI: ".concat(ari));
47
+ };
48
+
49
+ /**
50
+ * Rewrites a Jira field-value source ARI to the parent issue ARI used by AGG
51
+ * (`issueById`, media tokens, object-resolver). All other ARIs, including
52
+ * issue ARIs and unrecognized Media context ids, are returned as-is.
53
+ */
54
+ export var getJiraIssueAriFromSourceAri = function getJiraIssueAriFromSourceAri(_ref3) {
55
+ var ari = _ref3.ari;
56
+ var fieldValueParts = getFieldValueAriParts(ari);
57
+ if (fieldValueParts) {
58
+ return getJiraWorkItemAri({
59
+ cloudId: fieldValueParts.cloudId,
60
+ workItemId: fieldValueParts.issueId
61
+ });
62
+ }
63
+ return ari;
29
64
  };
@@ -5,6 +5,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
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
6
  import { logException } from '@atlaskit/editor-common/monitoring';
7
7
  import { fetchWithRetry } from '../../utils/retry';
8
+ import { getJiraIssueAriFromSourceAri } from './ari';
8
9
  var COMMON_HEADERS = {
9
10
  'Content-Type': 'application/json',
10
11
  Accept: 'application/json'
@@ -63,16 +64,19 @@ var getJiraMediaReadToken = /*#__PURE__*/function () {
63
64
  * Fetches a media read token for a Jira issue, to allow media uploaded to Jira
64
65
  * to be rendered in cross-product synced block references (e.g. in Confluence).
65
66
  *
66
- * @param issueAri - the Jira issue ARI (e.g. ari:cloud:jira:{cloudId}:issue/{issueId})
67
+ * @param sourceAri - the Jira issue ARI or field-value source ARI
67
68
  * @returns TokenData with token, config (clientId + fileStoreUrl), and optional collectionId
68
69
  */
69
70
  export var fetchJiraMediaToken = /*#__PURE__*/function () {
70
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(issueAri) {
71
- var _response$data, _mediaReadToken$token, _mediaReadToken$token2, response, mediaReadToken, clientId, endpointUrl, token, errorMsg, _t;
71
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(sourceAri) {
72
+ var _response$data, _mediaReadToken$token, _mediaReadToken$token2, issueAri, response, mediaReadToken, clientId, endpointUrl, token, errorMsg, _t;
72
73
  return _regeneratorRuntime.wrap(function (_context2) {
73
74
  while (1) switch (_context2.prev = _context2.next) {
74
75
  case 0:
75
76
  _context2.prev = 0;
77
+ issueAri = getJiraIssueAriFromSourceAri({
78
+ ari: sourceAri
79
+ });
76
80
  _context2.next = 1;
77
81
  return getJiraMediaReadToken(issueAri);
78
82
  case 1:
@@ -6,6 +6,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
6
6
  /* eslint-disable require-unicode-regexp */
7
7
 
8
8
  import { fetchWithRetry } from '../../utils/retry';
9
+ import { getJiraIssueAriFromSourceAri } from './ari';
9
10
  var COMMON_HEADERS = {
10
11
  'Content-Type': 'application/json',
11
12
  Accept: 'application/json'
@@ -24,7 +25,7 @@ var GET_SOURCE_INFO_OPERATION_NAME = 'EDITOR_SYNCED_BLOCK_GET_SOURCE_INFO';
24
25
  // SyncedLocationDropdown can render the correct ADS issue-type icon.
25
26
  var GET_SOURCE_INFO_QUERY = "query ".concat(GET_SOURCE_INFO_OPERATION_NAME, " ($id: ID!) {\n jira {\n\tissueById(id: $id) {\n\tid\n\twebUrl\n\tsummary\n\tissueType {\n\t\tname\n\t\tavatar {\n\t\txsmall\n\t\t}\n\t}\n\t}\n }}");
26
27
  var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
27
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(ari) {
28
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(issueAri) {
28
29
  var bodyData, response;
29
30
  return _regeneratorRuntime.wrap(function (_context) {
30
31
  while (1) switch (_context.prev = _context.next) {
@@ -33,7 +34,7 @@ var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
33
34
  query: GET_SOURCE_INFO_QUERY,
34
35
  operationName: GET_SOURCE_INFO_OPERATION_NAME,
35
36
  variables: {
36
- id: ari
37
+ id: issueAri
37
38
  }
38
39
  };
39
40
  _context.next = 1;
@@ -65,7 +66,7 @@ var getJiraWorkItemSourceInfo = /*#__PURE__*/function () {
65
66
  };
66
67
  }();
67
68
  var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
68
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(ari) {
69
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(sourceAri, issueAri) {
69
70
  var response, _payload$data, _payload$data2, payload, url, title;
70
71
  return _regeneratorRuntime.wrap(function (_context2) {
71
72
  while (1) switch (_context2.prev = _context2.next) {
@@ -78,7 +79,7 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
78
79
  Accept: 'application/json'
79
80
  },
80
81
  body: JSON.stringify({
81
- ari: ari
82
+ ari: issueAri
82
83
  })
83
84
  });
84
85
  case 1:
@@ -96,7 +97,7 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
96
97
  return _context2.abrupt("return", {
97
98
  url: typeof url === 'string' ? url : undefined,
98
99
  title: typeof title === 'string' ? title : undefined,
99
- sourceAri: ari
100
+ sourceAri: sourceAri
100
101
  });
101
102
  case 3:
102
103
  throw new Error("Failed to resolve ari: ".concat(response.statusText));
@@ -106,7 +107,7 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
106
107
  }
107
108
  }, _callee2);
108
109
  }));
109
- return function resolveNoAccessWorkItemInfo(_x2) {
110
+ return function resolveNoAccessWorkItemInfo(_x2, _x3) {
110
111
  return _ref2.apply(this, arguments);
111
112
  };
112
113
  }();
@@ -133,16 +134,21 @@ var resolveNoAccessWorkItemInfo = /*#__PURE__*/function () {
133
134
  */
134
135
  export var fetchJiraWorkItemInfo = /*#__PURE__*/function () {
135
136
  var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(workItemAri, hasAccess) {
136
- var _response$data, _contentData$issueTyp, _contentData$issueTyp2, response, contentData, webUrl, summary, issueTypeName, issueType;
137
+ var issueAri, _response$data, _contentData$issueTyp, _contentData$issueTyp2, response, contentData, webUrl, summary, issueTypeName, issueType;
137
138
  return _regeneratorRuntime.wrap(function (_context3) {
138
139
  while (1) switch (_context3.prev = _context3.next) {
139
140
  case 0:
141
+ // AGG `issueById` and object-resolver only understand issue ARIs. Field-value
142
+ // source ARIs keep their original identity on the returned `sourceAri`.
143
+ issueAri = getJiraIssueAriFromSourceAri({
144
+ ari: workItemAri
145
+ });
140
146
  if (!hasAccess) {
141
147
  _context3.next = 2;
142
148
  break;
143
149
  }
144
150
  _context3.next = 1;
145
- return getJiraWorkItemSourceInfo(workItemAri);
151
+ return getJiraWorkItemSourceInfo(issueAri);
146
152
  case 1:
147
153
  response = _context3.sent;
148
154
  contentData = (_response$data = response.data) === null || _response$data === void 0 || (_response$data = _response$data.jira) === null || _response$data === void 0 ? void 0 : _response$data.issueById;
@@ -163,7 +169,7 @@ export var fetchJiraWorkItemInfo = /*#__PURE__*/function () {
163
169
  }));
164
170
  case 2:
165
171
  _context3.next = 3;
166
- return resolveNoAccessWorkItemInfo(workItemAri);
172
+ return resolveNoAccessWorkItemInfo(workItemAri, issueAri);
167
173
  case 3:
168
174
  return _context3.abrupt("return", _context3.sent);
169
175
  case 4:
@@ -172,7 +178,7 @@ export var fetchJiraWorkItemInfo = /*#__PURE__*/function () {
172
178
  }
173
179
  }, _callee3);
174
180
  }));
175
- return function fetchJiraWorkItemInfo(_x3, _x4) {
181
+ return function fetchJiraWorkItemInfo(_x4, _x5) {
176
182
  return _ref3.apply(this, arguments);
177
183
  };
178
184
  }();
@@ -1,2 +1,2 @@
1
1
  /* eslint-disable @atlaskit/editor/no-re-export */
2
- export { getJiraWorkItemAri, getJiraWorkItemIdFromAri } from '../clients/jira/ari';
2
+ export { getJiraIssueAriFromSourceAri, getJiraWorkItemAri, getJiraWorkItemIdFromAri } from '../clients/jira/ari';
@@ -9,10 +9,20 @@ export declare const getJiraWorkItemAri: ({ cloudId, workItemId, }: {
9
9
  workItemId: string;
10
10
  }) => string;
11
11
  /**
12
- * Extracts the Jira work item ID from the Jira work item ARI
13
- * @param ari - the Jira work item ARI
12
+ * Extracts the Jira work item ID from an issue ARI or a field-value source ARI.
13
+ * Field identity stays on `sourceAri`; callers that need an issue id for AGG
14
+ * or media must not read `fieldId` from `blockAri`.
15
+ * @param ari - the Jira issue or issuefieldvalue ARI
14
16
  * @returns the Jira work item ID
15
17
  */
16
18
  export declare const getJiraWorkItemIdFromAri: ({ ari }: {
17
19
  ari: string;
18
20
  }) => string;
21
+ /**
22
+ * Rewrites a Jira field-value source ARI to the parent issue ARI used by AGG
23
+ * (`issueById`, media tokens, object-resolver). All other ARIs, including
24
+ * issue ARIs and unrecognized Media context ids, are returned as-is.
25
+ */
26
+ export declare const getJiraIssueAriFromSourceAri: ({ ari }: {
27
+ ari: string;
28
+ }) => string;
@@ -3,7 +3,7 @@ import type { TokenData } from '../confluence/fetchMediaToken';
3
3
  * Fetches a media read token for a Jira issue, to allow media uploaded to Jira
4
4
  * to be rendered in cross-product synced block references (e.g. in Confluence).
5
5
  *
6
- * @param issueAri - the Jira issue ARI (e.g. ari:cloud:jira:{cloudId}:issue/{issueId})
6
+ * @param sourceAri - the Jira issue ARI or field-value source ARI
7
7
  * @returns TokenData with token, config (clientId + fileStoreUrl), and optional collectionId
8
8
  */
9
- export declare const fetchJiraMediaToken: (issueAri: string) => Promise<TokenData>;
9
+ export declare const fetchJiraMediaToken: (sourceAri: string) => Promise<TokenData>;
@@ -1 +1 @@
1
- export { getJiraWorkItemAri, getJiraWorkItemIdFromAri } from '../clients/jira/ari';
1
+ export { getJiraIssueAriFromSourceAri, getJiraWorkItemAri, getJiraWorkItemIdFromAri, } from '../clients/jira/ari';
package/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "@atlaskit/node-data-provider": "^18.0.0",
24
24
  "@atlaskit/platform-feature-experiments": "^0.3.0",
25
25
  "@atlaskit/platform-feature-flags": "^2.2.0",
26
- "@atlaskit/tmp-editor-statsig": "^179.0.0",
26
+ "@atlaskit/tmp-editor-statsig": "^180.0.0",
27
27
  "@babel/runtime": "^7.0.0",
28
28
  "@compiled/react": "^1.0.2",
29
29
  "bind-event-listener": "^3.0.0",
@@ -33,7 +33,7 @@
33
33
  "uuid": "^11.1.1"
34
34
  },
35
35
  "peerDependencies": {
36
- "@atlaskit/editor-common": "^121.0.0",
36
+ "@atlaskit/editor-common": "^121.1.0",
37
37
  "react": "^18.2.0 || ^19.2.0"
38
38
  },
39
39
  "devDependencies": {
@@ -42,7 +42,7 @@
42
42
  "react-dom": "^19.2.0"
43
43
  },
44
44
  "name": "@atlaskit/editor-synced-block-provider",
45
- "version": "13.0.0",
45
+ "version": "13.1.1",
46
46
  "description": "Synced Block Provider for @atlaskit/editor-plugin-synced-block",
47
47
  "author": "Atlassian Pty Ltd",
48
48
  "license": "Apache-2.0",