@forge/bridge 2.5.6 → 2.6.0-next.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,17 @@
1
1
  # @forge/bridge
2
2
 
3
+ ## 2.6.0-next.1
4
+
5
+ ### Minor Changes
6
+
7
+ - cf983b29: Fix for downloading binary data from requestJira/requestConfluence API calls
8
+
9
+ ## 2.6.0-next.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 139a2cc: Fix support for uploading attachments via product fetch APIs
14
+
3
15
  ## 2.5.6
4
16
 
5
17
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/fetch/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAqB1C,eAAO,MAAM,eAAe,eAAgB,WAAW,oBAAoB,CAAC;kCAuB1C,MAAM,iBAAiB,WAAW,KAAG,QAAQ,QAAQ,CAAC;4BAG5D,MAAM,iBAAiB,WAAW,KAAG,QAAQ,QAAQ,CAAC;CAGjF,CAAC"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/fetch/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAqD1C,eAAO,MAAM,eAAe,eAAgB,WAAW,oBAAoB,CAAC;kCAyB1C,MAAM,iBAAiB,WAAW,KAAG,QAAQ,QAAQ,CAAC;4BAG5D,MAAM,iBAAiB,WAAW,KAAG,QAAQ,QAAQ,CAAC;CAGjF,CAAC"}
@@ -2,28 +2,50 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.productFetchApi = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const parseBodyAndHeaders = (init) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
6
- const req = new Request('', { body: init === null || init === void 0 ? void 0 : init.body, method: init === null || init === void 0 ? void 0 : init.method, headers: init === null || init === void 0 ? void 0 : init.headers });
7
- const body = req.method !== 'GET' ? yield req.text() : null;
5
+ const blobParser_1 = require("../utils/blobParser");
6
+ const parseFormData = (form) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
7
+ const parsed = {};
8
+ for (const [key, value] of form.entries()) {
9
+ if (key === 'file') {
10
+ const fileName = value.name;
11
+ const fileType = value.type;
12
+ parsed['file'] = yield (0, blobParser_1.blobToBase64)(value);
13
+ parsed['__fileName'] = fileName;
14
+ parsed['__fileType'] = fileType;
15
+ }
16
+ else {
17
+ parsed[key] = value;
18
+ }
19
+ }
20
+ return JSON.stringify(parsed);
21
+ });
22
+ const parseRequest = (init) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
23
+ const isFormData = (init === null || init === void 0 ? void 0 : init.body) instanceof FormData ? true : false;
24
+ const requestBody = isFormData ? yield parseFormData(init === null || init === void 0 ? void 0 : init.body) : init === null || init === void 0 ? void 0 : init.body;
25
+ const req = new Request('', { body: requestBody, method: init === null || init === void 0 ? void 0 : init.method, headers: init === null || init === void 0 ? void 0 : init.headers });
8
26
  const headers = Object.fromEntries(req.headers.entries());
27
+ const body = req.method !== 'GET' ? yield req.text() : null;
9
28
  return {
10
29
  body,
11
- headers: new Headers(headers)
30
+ headers: new Headers(headers),
31
+ isMultipartFormData: isFormData
12
32
  };
13
33
  });
14
34
  const productFetchApi = (callBridge) => {
15
35
  const fetch = (product, restPath, init) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
16
- const { body: requestBody, headers: requestHeaders } = yield parseBodyAndHeaders(init);
36
+ const { body: requestBody, headers: requestHeaders, isMultipartFormData } = yield parseRequest(init);
17
37
  if (!requestHeaders.has('X-Atlassian-Token')) {
18
38
  requestHeaders.set('X-Atlassian-Token', 'no-check');
19
39
  }
20
40
  const fetchPayload = {
21
41
  product,
22
42
  restPath,
23
- fetchRequestInit: Object.assign(Object.assign({}, init), { body: requestBody, headers: [...requestHeaders.entries()] })
43
+ fetchRequestInit: Object.assign(Object.assign({}, init), { body: requestBody, headers: [...requestHeaders.entries()] }),
44
+ isMultipartFormData
24
45
  };
25
- const { body, headers, statusText, status } = yield callBridge('fetchProduct', fetchPayload);
26
- return new Response(body || null, { headers, status, statusText });
46
+ const { body, headers, statusText, status, isAttachment } = yield callBridge('fetchProduct', fetchPayload);
47
+ const responseBody = isAttachment ? (0, blobParser_1.base64ToBlob)(body, headers['content-type']) : body;
48
+ return new Response(responseBody || null, { headers, status, statusText });
27
49
  });
28
50
  return {
29
51
  requestConfluence: (restPath, fetchOptions) => fetch('confluence', restPath, fetchOptions),
package/out/types.d.ts CHANGED
@@ -4,7 +4,11 @@ export declare type InvokePayload = {
4
4
  export declare type InvokeResponse = Record<string, any> | void;
5
5
  export declare type ProductFetchResponse = {
6
6
  body?: string;
7
- } & Pick<ResponseInit, 'headers' | 'status' | 'statusText'>;
7
+ headers: {
8
+ [key: string]: string;
9
+ };
10
+ isAttachment?: boolean;
11
+ } & Pick<ResponseInit, 'status' | 'statusText'>;
8
12
  export interface FullContext {
9
13
  accountId?: string;
10
14
  cloudId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oBAAY,aAAa,GAAG;KACzB,GAAG,IAAI,MAAM,GAAG,MAAM,GAAG,GAAG;CAC9B,CAAC;AAEF,oBAAY,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;AAExD,oBAAY,oBAAoB,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC,CAAC;AAE/G,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,aAAa;IACrB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,oBAAY,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oBAAY,aAAa,GAAG;KACzB,GAAG,IAAI,MAAM,GAAG,MAAM,GAAG,GAAG;CAC9B,CAAC;AAEF,oBAAY,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;AAExD,oBAAY,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACnC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,YAAY,CAAC,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,aAAa;IACrB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,oBAAY,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const base64ToBlob: (b64string: string | undefined, mimeType: string) => Blob | null;
2
+ export declare const blobToBase64: (blob: Blob) => Promise<string>;
3
+ //# sourceMappingURL=blobParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobParser.d.ts","sourceRoot":"","sources":["../../src/utils/blobParser.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,cAAe,MAAM,GAAG,SAAS,YAAY,MAAM,KAAG,IAAI,GAAG,IAgBrF,CAAC;AAEF,eAAO,MAAM,YAAY,SAAU,IAAI,KAAG,QAAQ,MAAM,CAUvD,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.blobToBase64 = exports.base64ToBlob = void 0;
4
+ const base64ToBlob = (b64string, mimeType) => {
5
+ if (!b64string) {
6
+ return null;
7
+ }
8
+ const base64Data = b64string.includes(';base64') ? b64string.split(',')[1] : b64string;
9
+ const byteCharacters = atob(base64Data);
10
+ const byteNumbers = new Array(byteCharacters.length);
11
+ for (let i = 0; i < byteCharacters.length; i++) {
12
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
13
+ }
14
+ const byteArray = new Uint8Array(byteNumbers);
15
+ return new Blob([byteArray], { type: mimeType });
16
+ };
17
+ exports.base64ToBlob = base64ToBlob;
18
+ const blobToBase64 = (blob) => {
19
+ return new Promise((resolve, reject) => {
20
+ const reader = new FileReader();
21
+ reader.onloadend = () => {
22
+ resolve(reader.result);
23
+ };
24
+ reader.onerror = reject;
25
+ reader.readAsDataURL(blob);
26
+ });
27
+ };
28
+ exports.blobToBase64 = blobToBase64;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/bridge",
3
- "version": "2.5.6",
3
+ "version": "2.6.0-next.1",
4
4
  "description": "Forge bridge API for custom UI apps",
5
5
  "author": "Atlassian",
6
6
  "license": "UNLICENSED",