@atlaskit/util-service-support 6.2.6 → 6.3.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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/util-service-support
2
2
 
3
+ ## 6.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#117306](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/117306)
8
+ [`d18a5954f7ca9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d18a5954f7ca9) -
9
+ Add utility function that supports multipart responses
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 6.2.7
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+
3
21
  ## 6.2.6
4
22
 
5
23
  ### Patch Changes
package/dist/cjs/index.js CHANGED
@@ -5,9 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  var _exportNames = {
8
- utils: true
8
+ utils: true,
9
+ multipartUtils: true
9
10
  };
10
- exports.utils = void 0;
11
+ exports.utils = exports.multipartUtils = void 0;
11
12
  var _types = require("./types");
12
13
  Object.keys(_types).forEach(function (key) {
13
14
  if (key === "default" || key === "__esModule") return;
@@ -33,6 +34,8 @@ Object.keys(_serviceResources).forEach(function (key) {
33
34
  });
34
35
  });
35
36
  var serviceUtils = _interopRequireWildcard(require("./serviceUtils"));
37
+ var multipartServiceUtils = _interopRequireWildcard(require("./multipartServiceUtils"));
36
38
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
37
39
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
38
- var utils = exports.utils = serviceUtils;
40
+ var utils = exports.utils = serviceUtils;
41
+ var multipartUtils = exports.multipartUtils = multipartServiceUtils;
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.requestServiceMultipart = void 0;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
11
+ var _browser = require("meros/browser");
12
+ var _types = require("./types");
13
+ var _shared = require("./shared");
14
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
15
+ var _featureFlagsAccessed = require("@atlaskit/react-ufo/feature-flags-accessed");
16
+ var _experienceTraceIdContext = require("@atlaskit/react-ufo/experience-trace-id-context");
17
+ 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; }
18
+ 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; }
19
+ /** Copied from meros types, as there are difficulties with resolving the type in CI */
20
+
21
+ /**
22
+ * Make a request that **may** result in an HTTP multipart response from the server.
23
+ * @returns an object with a parsed JSON body OR an object with the parts from
24
+ * the HTTP multipart response.
25
+ */
26
+ var _requestServiceMultipart = exports.requestServiceMultipart = /*#__PURE__*/function () {
27
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(serviceConfig) {
28
+ var options,
29
+ url,
30
+ securityProvider,
31
+ refreshedSecurityProvider,
32
+ path,
33
+ queryParams,
34
+ requestInit,
35
+ secOptions,
36
+ requestUrl,
37
+ headers,
38
+ credentials,
39
+ TRACING_HEADER_FOR_SERVICE_UTIL,
40
+ tracingHeaderEnabled,
41
+ tracingHeaders,
42
+ requestOptions,
43
+ fetchResponse,
44
+ parts,
45
+ _args = arguments;
46
+ return _regenerator.default.wrap(function _callee$(_context) {
47
+ while (1) switch (_context.prev = _context.next) {
48
+ case 0:
49
+ options = _args.length > 1 && _args[1] !== undefined ? _args[1] : _shared.defaultRequestServiceOptions;
50
+ url = serviceConfig.url, securityProvider = serviceConfig.securityProvider, refreshedSecurityProvider = serviceConfig.refreshedSecurityProvider;
51
+ path = options.path, queryParams = options.queryParams, requestInit = options.requestInit;
52
+ secOptions = securityProvider && securityProvider();
53
+ requestUrl = (0, _shared.buildUrl)(url, path, queryParams, secOptions);
54
+ headers = (0, _shared.buildHeaders)(secOptions, requestInit && requestInit.headers);
55
+ credentials = (0, _types.buildCredentials)(secOptions); // Get tracing headers from UFO
56
+ TRACING_HEADER_FOR_SERVICE_UTIL = 'platform_collab_provider_tracingheaders';
57
+ tracingHeaderEnabled = (0, _platformFeatureFlags.fg)('platform_collab_provider_tracingheaders');
58
+ (0, _featureFlagsAccessed.addFeatureFlagAccessed)(TRACING_HEADER_FOR_SERVICE_UTIL, tracingHeaderEnabled);
59
+ tracingHeaders = {};
60
+ if (tracingHeaderEnabled) {
61
+ tracingHeaders = (0, _experienceTraceIdContext.getActiveTraceHttpRequestHeaders)(url);
62
+ }
63
+ requestOptions = _objectSpread(_objectSpread({}, requestInit), {}, {
64
+ // populate headers mainly for the collab provider however
65
+ // other components which uses this util can get the header as well.
66
+ // Those tracing headers shall not incur any issues as long as backends handle them properly
67
+ headers: _objectSpread(_objectSpread({}, headers), tracingHeaders),
68
+ credentials: credentials
69
+ });
70
+ _context.next = 15;
71
+ return fetch(requestUrl, requestOptions);
72
+ case 15:
73
+ fetchResponse = _context.sent;
74
+ _context.next = 18;
75
+ return (0, _browser.meros)(fetchResponse);
76
+ case 18:
77
+ parts = _context.sent;
78
+ if (!(fetchResponse.ok && fetchResponse.status !== 204)) {
79
+ _context.next = 28;
80
+ break;
81
+ }
82
+ if (!(parts[Symbol.asyncIterator] < 'u')) {
83
+ _context.next = 22;
84
+ break;
85
+ }
86
+ return _context.abrupt("return", {
87
+ isMultipart: true,
88
+ parts: parts
89
+ });
90
+ case 22:
91
+ _context.next = 24;
92
+ return parts.json();
93
+ case 24:
94
+ _context.t0 = _context.sent;
95
+ return _context.abrupt("return", {
96
+ isMultipart: false,
97
+ body: _context.t0
98
+ });
99
+ case 28:
100
+ if (!(fetchResponse.status === 401 && refreshedSecurityProvider)) {
101
+ _context.next = 30;
102
+ break;
103
+ }
104
+ return _context.abrupt("return", refreshedSecurityProvider().then(function (newSecOptions) {
105
+ var retryServiceConfig = {
106
+ url: url,
107
+ securityProvider: function securityProvider() {
108
+ return newSecOptions;
109
+ }
110
+ };
111
+ return _requestServiceMultipart(retryServiceConfig, options);
112
+ }));
113
+ case 30:
114
+ return _context.abrupt("return", Promise.reject({
115
+ code: fetchResponse.status,
116
+ reason: fetchResponse.statusText
117
+ }));
118
+ case 31:
119
+ case "end":
120
+ return _context.stop();
121
+ }
122
+ }, _callee);
123
+ }));
124
+ return function requestServiceMultipart(_x) {
125
+ return _ref.apply(this, arguments);
126
+ };
127
+ }();
@@ -10,74 +10,9 @@ var _experienceTraceIdContext = require("@atlaskit/react-ufo/experience-trace-id
10
10
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
11
11
  var _featureFlagsAccessed = require("@atlaskit/react-ufo/feature-flags-accessed");
12
12
  var _types = require("./types");
13
+ var _shared = require("./shared");
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
- var defaultRequestServiceOptions = {};
16
- var buildUrl = function buildUrl(baseUrl) {
17
- var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
18
- var queryParams = arguments.length > 2 ? arguments[2] : undefined;
19
- var secOptions = arguments.length > 3 ? arguments[3] : undefined;
20
- var searchParam = new URLSearchParams(
21
- // For relative urls, the URL class requires base to be set. It's ignored if a url is not relative.
22
- // Since we only care about search params it is fine to have any base url here.
23
- new URL(baseUrl, 'https://BASE_FALLBACK').search || undefined);
24
- baseUrl = baseUrl.split('?')[0];
25
- if (queryParams) {
26
- for (var key in queryParams) {
27
- if ({}.hasOwnProperty.call(queryParams, key)) {
28
- searchParam.append(key, queryParams[key]);
29
- }
30
- }
31
- }
32
- if (secOptions && secOptions.params) {
33
- for (var _key in secOptions.params) {
34
- if ({}.hasOwnProperty.call(secOptions.params, _key)) {
35
- var values = secOptions.params[_key];
36
- if (Array.isArray(values)) {
37
- for (var i = 0; i < values.length; i++) {
38
- searchParam.append(_key, values[i]);
39
- }
40
- } else {
41
- searchParam.append(_key, values);
42
- }
43
- }
44
- }
45
- }
46
- var separator = '';
47
- if (path && baseUrl.substr(-1) !== '/' && !path.startsWith('/')) {
48
- separator = '/';
49
- }
50
- var params = searchParam.toString();
51
- if (params) {
52
- params = '?' + params;
53
- }
54
- return "".concat(baseUrl).concat(separator).concat(path).concat(params);
55
- };
56
- var addToHeaders = function addToHeaders(headers, keyValues) {
57
- if (keyValues) {
58
- for (var key in keyValues) {
59
- if ({}.hasOwnProperty.call(keyValues, key)) {
60
- var values = keyValues[key];
61
- if (Array.isArray(values)) {
62
- for (var i = 0; i < values.length; i++) {
63
- headers[key] = values[i];
64
- }
65
- } else {
66
- headers[key] = values;
67
- }
68
- }
69
- }
70
- }
71
- };
72
- var buildHeaders = function buildHeaders(secOptions, extraHeaders) {
73
- var headers = {};
74
- addToHeaders(headers, extraHeaders);
75
- if (secOptions) {
76
- addToHeaders(headers, secOptions.headers);
77
- }
78
- return headers;
79
- };
80
-
81
16
  /**
82
17
  * @returns Promise containing the json response
83
18
  */
@@ -85,17 +20,17 @@ var _requestService = exports.requestService = function requestService(serviceCo
85
20
  var url = serviceConfig.url,
86
21
  securityProvider = serviceConfig.securityProvider,
87
22
  refreshedSecurityProvider = serviceConfig.refreshedSecurityProvider;
88
- var _ref = options || defaultRequestServiceOptions,
23
+ var _ref = options || _shared.defaultRequestServiceOptions,
89
24
  path = _ref.path,
90
25
  queryParams = _ref.queryParams,
91
26
  requestInit = _ref.requestInit;
92
27
  var secOptions = securityProvider && securityProvider();
93
- var requestUrl = buildUrl(url, path, queryParams, secOptions);
94
- var headers = buildHeaders(secOptions, requestInit && requestInit.headers);
28
+ var requestUrl = (0, _shared.buildUrl)(url, path, queryParams, secOptions);
29
+ var headers = (0, _shared.buildHeaders)(secOptions, requestInit && requestInit.headers);
95
30
  var credentials = (0, _types.buildCredentials)(secOptions);
96
31
  var ignoreResponsePayload = (options === null || options === void 0 ? void 0 : options.ignoreResponsePayload) || false;
97
32
 
98
- //Get tracing headers from UFO
33
+ // Get tracing headers from UFO
99
34
  var TRACING_HEADER_FOR_SERVICE_UTIL = 'platform_collab_provider_tracingheaders';
100
35
  var tracingHeaderEnabled = (0, _platformFeatureFlags.fg)('platform_collab_provider_tracingheaders');
101
36
  (0, _featureFlagsAccessed.addFeatureFlagAccessed)(TRACING_HEADER_FOR_SERVICE_UTIL, tracingHeaderEnabled);
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.defaultRequestServiceOptions = exports.buildUrl = exports.buildHeaders = void 0;
7
+ var defaultRequestServiceOptions = exports.defaultRequestServiceOptions = {};
8
+ var buildUrl = exports.buildUrl = function buildUrl(baseUrl) {
9
+ var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
10
+ var queryParams = arguments.length > 2 ? arguments[2] : undefined;
11
+ var secOptions = arguments.length > 3 ? arguments[3] : undefined;
12
+ var searchParam = new URLSearchParams(
13
+ // For relative urls, the URL class requires base to be set. It's ignored if a url is not relative.
14
+ // Since we only care about search params it is fine to have any base url here.
15
+ new URL(baseUrl, 'https://BASE_FALLBACK').search || undefined);
16
+ baseUrl = baseUrl.split('?')[0];
17
+ if (queryParams) {
18
+ for (var key in queryParams) {
19
+ if ({}.hasOwnProperty.call(queryParams, key)) {
20
+ searchParam.append(key, queryParams[key]);
21
+ }
22
+ }
23
+ }
24
+ if (secOptions && secOptions.params) {
25
+ for (var _key in secOptions.params) {
26
+ if ({}.hasOwnProperty.call(secOptions.params, _key)) {
27
+ var values = secOptions.params[_key];
28
+ if (Array.isArray(values)) {
29
+ for (var i = 0; i < values.length; i++) {
30
+ searchParam.append(_key, values[i]);
31
+ }
32
+ } else {
33
+ searchParam.append(_key, values);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ var separator = '';
39
+ if (path && baseUrl.substr(-1) !== '/' && !path.startsWith('/')) {
40
+ separator = '/';
41
+ }
42
+ var params = searchParam.toString();
43
+ if (params) {
44
+ params = '?' + params;
45
+ }
46
+ return "".concat(baseUrl).concat(separator).concat(path).concat(params);
47
+ };
48
+ var addToHeaders = function addToHeaders(headers, keyValues) {
49
+ if (keyValues) {
50
+ for (var key in keyValues) {
51
+ if ({}.hasOwnProperty.call(keyValues, key)) {
52
+ var values = keyValues[key];
53
+ if (Array.isArray(values)) {
54
+ for (var i = 0; i < values.length; i++) {
55
+ headers[key] = values[i];
56
+ }
57
+ } else {
58
+ headers[key] = values;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ };
64
+ var buildHeaders = exports.buildHeaders = function buildHeaders(secOptions, extraHeaders) {
65
+ var headers = {};
66
+ addToHeaders(headers, extraHeaders);
67
+ if (secOptions) {
68
+ addToHeaders(headers, secOptions.headers);
69
+ }
70
+ return headers;
71
+ };
@@ -1,4 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './serviceResources';
3
3
  import * as serviceUtils from './serviceUtils';
4
- export const utils = serviceUtils;
4
+ import * as multipartServiceUtils from './multipartServiceUtils';
5
+ export const utils = serviceUtils;
6
+ export const multipartUtils = multipartServiceUtils;
@@ -0,0 +1,82 @@
1
+ import { meros } from 'meros/browser';
2
+ import { buildCredentials } from './types';
3
+ import { buildHeaders, buildUrl, defaultRequestServiceOptions } from './shared';
4
+ import { fg } from '@atlaskit/platform-feature-flags';
5
+ import { addFeatureFlagAccessed } from '@atlaskit/react-ufo/feature-flags-accessed';
6
+ import { getActiveTraceHttpRequestHeaders } from '@atlaskit/react-ufo/experience-trace-id-context';
7
+
8
+ /** Copied from meros types, as there are difficulties with resolving the type in CI */
9
+
10
+ /**
11
+ * Make a request that **may** result in an HTTP multipart response from the server.
12
+ * @returns an object with a parsed JSON body OR an object with the parts from
13
+ * the HTTP multipart response.
14
+ */
15
+ export const requestServiceMultipart = async (serviceConfig, options = defaultRequestServiceOptions) => {
16
+ const {
17
+ url,
18
+ securityProvider,
19
+ refreshedSecurityProvider
20
+ } = serviceConfig;
21
+ const {
22
+ path,
23
+ queryParams,
24
+ requestInit
25
+ } = options;
26
+ const secOptions = securityProvider && securityProvider();
27
+ const requestUrl = buildUrl(url, path, queryParams, secOptions);
28
+ const headers = buildHeaders(secOptions, requestInit && requestInit.headers);
29
+ const credentials = buildCredentials(secOptions);
30
+
31
+ // Get tracing headers from UFO
32
+ const TRACING_HEADER_FOR_SERVICE_UTIL = 'platform_collab_provider_tracingheaders';
33
+ const tracingHeaderEnabled = fg('platform_collab_provider_tracingheaders');
34
+ addFeatureFlagAccessed(TRACING_HEADER_FOR_SERVICE_UTIL, tracingHeaderEnabled);
35
+ let tracingHeaders = {};
36
+ if (tracingHeaderEnabled) {
37
+ tracingHeaders = getActiveTraceHttpRequestHeaders(url);
38
+ }
39
+ const requestOptions = {
40
+ ...requestInit,
41
+ // populate headers mainly for the collab provider however
42
+ // other components which uses this util can get the header as well.
43
+ // Those tracing headers shall not incur any issues as long as backends handle them properly
44
+ headers: {
45
+ ...headers,
46
+ ...tracingHeaders
47
+ },
48
+ credentials
49
+ };
50
+ const fetchResponse = await fetch(requestUrl, requestOptions);
51
+ const parts = await meros(fetchResponse);
52
+ if (fetchResponse.ok && fetchResponse.status !== 204) {
53
+ if (parts[Symbol.asyncIterator] < 'u') {
54
+ // this lets us know that the response is multipart
55
+ //
56
+ // ((parts as PartsType)[Symbol.asyncIterator] as any) < 'u' came from the `meros` docs:
57
+ // https://github.com/maraisr/meros/blob/dec4feaa24090b94e8ac42fab1aff38a1e521680/readme.md
58
+ // Look for expand section `If the content-type is NOT a multipart, then meros will resolve with the response argument.`
59
+ return {
60
+ isMultipart: true,
61
+ parts: parts
62
+ };
63
+ }
64
+ return {
65
+ isMultipart: false,
66
+ body: await parts.json()
67
+ };
68
+ } else if (fetchResponse.status === 401 && refreshedSecurityProvider) {
69
+ // auth issue - try once
70
+ return refreshedSecurityProvider().then(newSecOptions => {
71
+ const retryServiceConfig = {
72
+ url,
73
+ securityProvider: () => newSecOptions
74
+ };
75
+ return requestServiceMultipart(retryServiceConfig, options);
76
+ });
77
+ }
78
+ return Promise.reject({
79
+ code: fetchResponse.status,
80
+ reason: fetchResponse.statusText
81
+ });
82
+ };
@@ -2,68 +2,7 @@ import { getActiveTraceHttpRequestHeaders } from '@atlaskit/react-ufo/experience
2
2
  import { fg } from '@atlaskit/platform-feature-flags';
3
3
  import { addFeatureFlagAccessed } from '@atlaskit/react-ufo/feature-flags-accessed';
4
4
  import { buildCredentials } from './types';
5
- const defaultRequestServiceOptions = {};
6
- const buildUrl = (baseUrl, path = '', queryParams, secOptions) => {
7
- const searchParam = new URLSearchParams(
8
- // For relative urls, the URL class requires base to be set. It's ignored if a url is not relative.
9
- // Since we only care about search params it is fine to have any base url here.
10
- new URL(baseUrl, 'https://BASE_FALLBACK').search || undefined);
11
- baseUrl = baseUrl.split('?')[0];
12
- if (queryParams) {
13
- for (const key in queryParams) {
14
- if ({}.hasOwnProperty.call(queryParams, key)) {
15
- searchParam.append(key, queryParams[key]);
16
- }
17
- }
18
- }
19
- if (secOptions && secOptions.params) {
20
- for (const key in secOptions.params) {
21
- if ({}.hasOwnProperty.call(secOptions.params, key)) {
22
- const values = secOptions.params[key];
23
- if (Array.isArray(values)) {
24
- for (let i = 0; i < values.length; i++) {
25
- searchParam.append(key, values[i]);
26
- }
27
- } else {
28
- searchParam.append(key, values);
29
- }
30
- }
31
- }
32
- }
33
- let separator = '';
34
- if (path && baseUrl.substr(-1) !== '/' && !path.startsWith('/')) {
35
- separator = '/';
36
- }
37
- let params = searchParam.toString();
38
- if (params) {
39
- params = '?' + params;
40
- }
41
- return `${baseUrl}${separator}${path}${params}`;
42
- };
43
- const addToHeaders = (headers, keyValues) => {
44
- if (keyValues) {
45
- for (const key in keyValues) {
46
- if ({}.hasOwnProperty.call(keyValues, key)) {
47
- const values = keyValues[key];
48
- if (Array.isArray(values)) {
49
- for (let i = 0; i < values.length; i++) {
50
- headers[key] = values[i];
51
- }
52
- } else {
53
- headers[key] = values;
54
- }
55
- }
56
- }
57
- }
58
- };
59
- const buildHeaders = (secOptions, extraHeaders) => {
60
- const headers = {};
61
- addToHeaders(headers, extraHeaders);
62
- if (secOptions) {
63
- addToHeaders(headers, secOptions.headers);
64
- }
65
- return headers;
66
- };
5
+ import { defaultRequestServiceOptions, buildUrl, buildHeaders } from './shared';
67
6
 
68
7
  /**
69
8
  * @returns Promise containing the json response
@@ -85,7 +24,7 @@ export const requestService = (serviceConfig, options) => {
85
24
  const credentials = buildCredentials(secOptions);
86
25
  const ignoreResponsePayload = (options === null || options === void 0 ? void 0 : options.ignoreResponsePayload) || false;
87
26
 
88
- //Get tracing headers from UFO
27
+ // Get tracing headers from UFO
89
28
  const TRACING_HEADER_FOR_SERVICE_UTIL = 'platform_collab_provider_tracingheaders';
90
29
  const tracingHeaderEnabled = fg('platform_collab_provider_tracingheaders');
91
30
  addFeatureFlagAccessed(TRACING_HEADER_FOR_SERVICE_UTIL, tracingHeaderEnabled);
@@ -0,0 +1,62 @@
1
+ export const defaultRequestServiceOptions = {};
2
+ export const buildUrl = (baseUrl, path = '', queryParams, secOptions) => {
3
+ const searchParam = new URLSearchParams(
4
+ // For relative urls, the URL class requires base to be set. It's ignored if a url is not relative.
5
+ // Since we only care about search params it is fine to have any base url here.
6
+ new URL(baseUrl, 'https://BASE_FALLBACK').search || undefined);
7
+ baseUrl = baseUrl.split('?')[0];
8
+ if (queryParams) {
9
+ for (const key in queryParams) {
10
+ if ({}.hasOwnProperty.call(queryParams, key)) {
11
+ searchParam.append(key, queryParams[key]);
12
+ }
13
+ }
14
+ }
15
+ if (secOptions && secOptions.params) {
16
+ for (const key in secOptions.params) {
17
+ if ({}.hasOwnProperty.call(secOptions.params, key)) {
18
+ const values = secOptions.params[key];
19
+ if (Array.isArray(values)) {
20
+ for (let i = 0; i < values.length; i++) {
21
+ searchParam.append(key, values[i]);
22
+ }
23
+ } else {
24
+ searchParam.append(key, values);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ let separator = '';
30
+ if (path && baseUrl.substr(-1) !== '/' && !path.startsWith('/')) {
31
+ separator = '/';
32
+ }
33
+ let params = searchParam.toString();
34
+ if (params) {
35
+ params = '?' + params;
36
+ }
37
+ return `${baseUrl}${separator}${path}${params}`;
38
+ };
39
+ const addToHeaders = (headers, keyValues) => {
40
+ if (keyValues) {
41
+ for (const key in keyValues) {
42
+ if ({}.hasOwnProperty.call(keyValues, key)) {
43
+ const values = keyValues[key];
44
+ if (Array.isArray(values)) {
45
+ for (let i = 0; i < values.length; i++) {
46
+ headers[key] = values[i];
47
+ }
48
+ } else {
49
+ headers[key] = values;
50
+ }
51
+ }
52
+ }
53
+ }
54
+ };
55
+ export const buildHeaders = (secOptions, extraHeaders) => {
56
+ const headers = {};
57
+ addToHeaders(headers, extraHeaders);
58
+ if (secOptions) {
59
+ addToHeaders(headers, secOptions.headers);
60
+ }
61
+ return headers;
62
+ };
package/dist/esm/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './serviceResources';
3
3
  import * as serviceUtils from './serviceUtils';
4
- export var utils = serviceUtils;
4
+ import * as multipartServiceUtils from './multipartServiceUtils';
5
+ export var utils = serviceUtils;
6
+ export var multipartUtils = multipartServiceUtils;
@@ -0,0 +1,122 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
4
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
+ import { meros } from 'meros/browser';
7
+ import { buildCredentials } from './types';
8
+ import { buildHeaders, buildUrl, defaultRequestServiceOptions } from './shared';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
10
+ import { addFeatureFlagAccessed } from '@atlaskit/react-ufo/feature-flags-accessed';
11
+ import { getActiveTraceHttpRequestHeaders } from '@atlaskit/react-ufo/experience-trace-id-context';
12
+
13
+ /** Copied from meros types, as there are difficulties with resolving the type in CI */
14
+
15
+ /**
16
+ * Make a request that **may** result in an HTTP multipart response from the server.
17
+ * @returns an object with a parsed JSON body OR an object with the parts from
18
+ * the HTTP multipart response.
19
+ */
20
+ var _requestServiceMultipart = /*#__PURE__*/function () {
21
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(serviceConfig) {
22
+ var options,
23
+ url,
24
+ securityProvider,
25
+ refreshedSecurityProvider,
26
+ path,
27
+ queryParams,
28
+ requestInit,
29
+ secOptions,
30
+ requestUrl,
31
+ headers,
32
+ credentials,
33
+ TRACING_HEADER_FOR_SERVICE_UTIL,
34
+ tracingHeaderEnabled,
35
+ tracingHeaders,
36
+ requestOptions,
37
+ fetchResponse,
38
+ parts,
39
+ _args = arguments;
40
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
41
+ while (1) switch (_context.prev = _context.next) {
42
+ case 0:
43
+ options = _args.length > 1 && _args[1] !== undefined ? _args[1] : defaultRequestServiceOptions;
44
+ url = serviceConfig.url, securityProvider = serviceConfig.securityProvider, refreshedSecurityProvider = serviceConfig.refreshedSecurityProvider;
45
+ path = options.path, queryParams = options.queryParams, requestInit = options.requestInit;
46
+ secOptions = securityProvider && securityProvider();
47
+ requestUrl = buildUrl(url, path, queryParams, secOptions);
48
+ headers = buildHeaders(secOptions, requestInit && requestInit.headers);
49
+ credentials = buildCredentials(secOptions); // Get tracing headers from UFO
50
+ TRACING_HEADER_FOR_SERVICE_UTIL = 'platform_collab_provider_tracingheaders';
51
+ tracingHeaderEnabled = fg('platform_collab_provider_tracingheaders');
52
+ addFeatureFlagAccessed(TRACING_HEADER_FOR_SERVICE_UTIL, tracingHeaderEnabled);
53
+ tracingHeaders = {};
54
+ if (tracingHeaderEnabled) {
55
+ tracingHeaders = getActiveTraceHttpRequestHeaders(url);
56
+ }
57
+ requestOptions = _objectSpread(_objectSpread({}, requestInit), {}, {
58
+ // populate headers mainly for the collab provider however
59
+ // other components which uses this util can get the header as well.
60
+ // Those tracing headers shall not incur any issues as long as backends handle them properly
61
+ headers: _objectSpread(_objectSpread({}, headers), tracingHeaders),
62
+ credentials: credentials
63
+ });
64
+ _context.next = 15;
65
+ return fetch(requestUrl, requestOptions);
66
+ case 15:
67
+ fetchResponse = _context.sent;
68
+ _context.next = 18;
69
+ return meros(fetchResponse);
70
+ case 18:
71
+ parts = _context.sent;
72
+ if (!(fetchResponse.ok && fetchResponse.status !== 204)) {
73
+ _context.next = 28;
74
+ break;
75
+ }
76
+ if (!(parts[Symbol.asyncIterator] < 'u')) {
77
+ _context.next = 22;
78
+ break;
79
+ }
80
+ return _context.abrupt("return", {
81
+ isMultipart: true,
82
+ parts: parts
83
+ });
84
+ case 22:
85
+ _context.next = 24;
86
+ return parts.json();
87
+ case 24:
88
+ _context.t0 = _context.sent;
89
+ return _context.abrupt("return", {
90
+ isMultipart: false,
91
+ body: _context.t0
92
+ });
93
+ case 28:
94
+ if (!(fetchResponse.status === 401 && refreshedSecurityProvider)) {
95
+ _context.next = 30;
96
+ break;
97
+ }
98
+ return _context.abrupt("return", refreshedSecurityProvider().then(function (newSecOptions) {
99
+ var retryServiceConfig = {
100
+ url: url,
101
+ securityProvider: function securityProvider() {
102
+ return newSecOptions;
103
+ }
104
+ };
105
+ return _requestServiceMultipart(retryServiceConfig, options);
106
+ }));
107
+ case 30:
108
+ return _context.abrupt("return", Promise.reject({
109
+ code: fetchResponse.status,
110
+ reason: fetchResponse.statusText
111
+ }));
112
+ case 31:
113
+ case "end":
114
+ return _context.stop();
115
+ }
116
+ }, _callee);
117
+ }));
118
+ return function requestServiceMultipart(_x) {
119
+ return _ref.apply(this, arguments);
120
+ };
121
+ }();
122
+ export { _requestServiceMultipart as requestServiceMultipart };
@@ -5,71 +5,7 @@ import { getActiveTraceHttpRequestHeaders } from '@atlaskit/react-ufo/experience
5
5
  import { fg } from '@atlaskit/platform-feature-flags';
6
6
  import { addFeatureFlagAccessed } from '@atlaskit/react-ufo/feature-flags-accessed';
7
7
  import { buildCredentials } from './types';
8
- var defaultRequestServiceOptions = {};
9
- var buildUrl = function buildUrl(baseUrl) {
10
- var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
11
- var queryParams = arguments.length > 2 ? arguments[2] : undefined;
12
- var secOptions = arguments.length > 3 ? arguments[3] : undefined;
13
- var searchParam = new URLSearchParams(
14
- // For relative urls, the URL class requires base to be set. It's ignored if a url is not relative.
15
- // Since we only care about search params it is fine to have any base url here.
16
- new URL(baseUrl, 'https://BASE_FALLBACK').search || undefined);
17
- baseUrl = baseUrl.split('?')[0];
18
- if (queryParams) {
19
- for (var key in queryParams) {
20
- if ({}.hasOwnProperty.call(queryParams, key)) {
21
- searchParam.append(key, queryParams[key]);
22
- }
23
- }
24
- }
25
- if (secOptions && secOptions.params) {
26
- for (var _key in secOptions.params) {
27
- if ({}.hasOwnProperty.call(secOptions.params, _key)) {
28
- var values = secOptions.params[_key];
29
- if (Array.isArray(values)) {
30
- for (var i = 0; i < values.length; i++) {
31
- searchParam.append(_key, values[i]);
32
- }
33
- } else {
34
- searchParam.append(_key, values);
35
- }
36
- }
37
- }
38
- }
39
- var separator = '';
40
- if (path && baseUrl.substr(-1) !== '/' && !path.startsWith('/')) {
41
- separator = '/';
42
- }
43
- var params = searchParam.toString();
44
- if (params) {
45
- params = '?' + params;
46
- }
47
- return "".concat(baseUrl).concat(separator).concat(path).concat(params);
48
- };
49
- var addToHeaders = function addToHeaders(headers, keyValues) {
50
- if (keyValues) {
51
- for (var key in keyValues) {
52
- if ({}.hasOwnProperty.call(keyValues, key)) {
53
- var values = keyValues[key];
54
- if (Array.isArray(values)) {
55
- for (var i = 0; i < values.length; i++) {
56
- headers[key] = values[i];
57
- }
58
- } else {
59
- headers[key] = values;
60
- }
61
- }
62
- }
63
- }
64
- };
65
- var buildHeaders = function buildHeaders(secOptions, extraHeaders) {
66
- var headers = {};
67
- addToHeaders(headers, extraHeaders);
68
- if (secOptions) {
69
- addToHeaders(headers, secOptions.headers);
70
- }
71
- return headers;
72
- };
8
+ import { defaultRequestServiceOptions, buildUrl, buildHeaders } from './shared';
73
9
 
74
10
  /**
75
11
  * @returns Promise containing the json response
@@ -88,7 +24,7 @@ var _requestService = function requestService(serviceConfig, options) {
88
24
  var credentials = buildCredentials(secOptions);
89
25
  var ignoreResponsePayload = (options === null || options === void 0 ? void 0 : options.ignoreResponsePayload) || false;
90
26
 
91
- //Get tracing headers from UFO
27
+ // Get tracing headers from UFO
92
28
  var TRACING_HEADER_FOR_SERVICE_UTIL = 'platform_collab_provider_tracingheaders';
93
29
  var tracingHeaderEnabled = fg('platform_collab_provider_tracingheaders');
94
30
  addFeatureFlagAccessed(TRACING_HEADER_FOR_SERVICE_UTIL, tracingHeaderEnabled);
@@ -0,0 +1,65 @@
1
+ export var defaultRequestServiceOptions = {};
2
+ export var buildUrl = function buildUrl(baseUrl) {
3
+ var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
4
+ var queryParams = arguments.length > 2 ? arguments[2] : undefined;
5
+ var secOptions = arguments.length > 3 ? arguments[3] : undefined;
6
+ var searchParam = new URLSearchParams(
7
+ // For relative urls, the URL class requires base to be set. It's ignored if a url is not relative.
8
+ // Since we only care about search params it is fine to have any base url here.
9
+ new URL(baseUrl, 'https://BASE_FALLBACK').search || undefined);
10
+ baseUrl = baseUrl.split('?')[0];
11
+ if (queryParams) {
12
+ for (var key in queryParams) {
13
+ if ({}.hasOwnProperty.call(queryParams, key)) {
14
+ searchParam.append(key, queryParams[key]);
15
+ }
16
+ }
17
+ }
18
+ if (secOptions && secOptions.params) {
19
+ for (var _key in secOptions.params) {
20
+ if ({}.hasOwnProperty.call(secOptions.params, _key)) {
21
+ var values = secOptions.params[_key];
22
+ if (Array.isArray(values)) {
23
+ for (var i = 0; i < values.length; i++) {
24
+ searchParam.append(_key, values[i]);
25
+ }
26
+ } else {
27
+ searchParam.append(_key, values);
28
+ }
29
+ }
30
+ }
31
+ }
32
+ var separator = '';
33
+ if (path && baseUrl.substr(-1) !== '/' && !path.startsWith('/')) {
34
+ separator = '/';
35
+ }
36
+ var params = searchParam.toString();
37
+ if (params) {
38
+ params = '?' + params;
39
+ }
40
+ return "".concat(baseUrl).concat(separator).concat(path).concat(params);
41
+ };
42
+ var addToHeaders = function addToHeaders(headers, keyValues) {
43
+ if (keyValues) {
44
+ for (var key in keyValues) {
45
+ if ({}.hasOwnProperty.call(keyValues, key)) {
46
+ var values = keyValues[key];
47
+ if (Array.isArray(values)) {
48
+ for (var i = 0; i < values.length; i++) {
49
+ headers[key] = values[i];
50
+ }
51
+ } else {
52
+ headers[key] = values;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ };
58
+ export var buildHeaders = function buildHeaders(secOptions, extraHeaders) {
59
+ var headers = {};
60
+ addToHeaders(headers, extraHeaders);
61
+ if (secOptions) {
62
+ addToHeaders(headers, secOptions.headers);
63
+ }
64
+ return headers;
65
+ };
@@ -1,4 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './serviceResources';
3
3
  import * as serviceUtils from './serviceUtils';
4
+ import * as multipartServiceUtils from './multipartServiceUtils';
4
5
  export declare const utils: typeof serviceUtils;
6
+ export declare const multipartUtils: typeof multipartServiceUtils;
@@ -0,0 +1,29 @@
1
+ import { type RequestServiceOptions, type ServiceConfig } from './types';
2
+ type PartsType = AsyncGenerator<Part<object, string>, unknown, unknown>;
3
+ type MultiPartFetchResult = {
4
+ isMultipart: true;
5
+ parts: PartsType;
6
+ };
7
+ type BodyResult<T> = {
8
+ isMultipart: false;
9
+ body: T;
10
+ };
11
+ type RequestServiceResult<BodyType> = MultiPartFetchResult | BodyResult<BodyType>;
12
+ /** Copied from meros types, as there are difficulties with resolving the type in CI */
13
+ export type Part<Body, Fallback> = {
14
+ json: false;
15
+ headers: Record<string, string>;
16
+ body: Fallback;
17
+ } | {
18
+ json: true;
19
+ headers: Record<string, string>;
20
+ body: Body;
21
+ };
22
+ type Options = Omit<RequestServiceOptions, 'ignoreResponsePayload'>;
23
+ /**
24
+ * Make a request that **may** result in an HTTP multipart response from the server.
25
+ * @returns an object with a parsed JSON body OR an object with the parts from
26
+ * the HTTP multipart response.
27
+ */
28
+ export declare const requestServiceMultipart: <T>(serviceConfig: ServiceConfig, options?: Options) => Promise<RequestServiceResult<T>>;
29
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { RequestServiceOptions, KeyValues, SecurityOptions } from './types';
2
+ export declare const defaultRequestServiceOptions: RequestServiceOptions;
3
+ export declare const buildUrl: (baseUrl: string, path?: string, queryParams?: KeyValues, secOptions?: SecurityOptions) => string;
4
+ export declare const buildHeaders: (secOptions?: SecurityOptions, extraHeaders?: KeyValues) => KeyValues;
@@ -1,4 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './serviceResources';
3
3
  import * as serviceUtils from './serviceUtils';
4
+ import * as multipartServiceUtils from './multipartServiceUtils';
4
5
  export declare const utils: typeof serviceUtils;
6
+ export declare const multipartUtils: typeof multipartServiceUtils;
@@ -0,0 +1,29 @@
1
+ import { type RequestServiceOptions, type ServiceConfig } from './types';
2
+ type PartsType = AsyncGenerator<Part<object, string>, unknown, unknown>;
3
+ type MultiPartFetchResult = {
4
+ isMultipart: true;
5
+ parts: PartsType;
6
+ };
7
+ type BodyResult<T> = {
8
+ isMultipart: false;
9
+ body: T;
10
+ };
11
+ type RequestServiceResult<BodyType> = MultiPartFetchResult | BodyResult<BodyType>;
12
+ /** Copied from meros types, as there are difficulties with resolving the type in CI */
13
+ export type Part<Body, Fallback> = {
14
+ json: false;
15
+ headers: Record<string, string>;
16
+ body: Fallback;
17
+ } | {
18
+ json: true;
19
+ headers: Record<string, string>;
20
+ body: Body;
21
+ };
22
+ type Options = Omit<RequestServiceOptions, 'ignoreResponsePayload'>;
23
+ /**
24
+ * Make a request that **may** result in an HTTP multipart response from the server.
25
+ * @returns an object with a parsed JSON body OR an object with the parts from
26
+ * the HTTP multipart response.
27
+ */
28
+ export declare const requestServiceMultipart: <T>(serviceConfig: ServiceConfig, options?: Options) => Promise<RequestServiceResult<T>>;
29
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { RequestServiceOptions, KeyValues, SecurityOptions } from './types';
2
+ export declare const defaultRequestServiceOptions: RequestServiceOptions;
3
+ export declare const buildUrl: (baseUrl: string, path?: string, queryParams?: KeyValues, secOptions?: SecurityOptions) => string;
4
+ export declare const buildHeaders: (secOptions?: SecurityOptions, extraHeaders?: KeyValues) => KeyValues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/util-service-support",
3
- "version": "6.2.6",
3
+ "version": "6.3.0",
4
4
  "description": "A library of support classes for integrating React components with REST HTTP services",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -34,9 +34,10 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "@atlaskit/platform-feature-flags": "^1.0.0",
38
- "@atlaskit/react-ufo": "^2.14.0",
39
- "@babel/runtime": "^7.0.0"
37
+ "@atlaskit/platform-feature-flags": "^1.1.0",
38
+ "@atlaskit/react-ufo": "^3.4.0",
39
+ "@babel/runtime": "^7.0.0",
40
+ "meros": "^1.3.0"
40
41
  },
41
42
  "devDependencies": {
42
43
  "es6-promise": "^4.0.5",