@forge/bridge 5.6.1-next.5-experimental-44e92a2 → 5.7.0-next.10

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,19 +1,36 @@
1
1
  # @forge/bridge
2
2
 
3
- ## 5.6.1-next.5-experimental-44e92a2
3
+ ## 5.7.0-next.10
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - 94243f1: Split development and contribution guidelines
8
- - d9e48cd: minor update to tsconfig
9
- - Updated dependencies [b3792e4]
10
- - Updated dependencies [0ea6722]
7
+ - eda5e4f: Adds new bridge method objectStore.delete
8
+
9
+ ## 5.7.0-next.9
10
+
11
+ ### Patch Changes
12
+
13
+ - a03c9c5: Adds new bridge method objectStore.getMetadata
14
+
15
+ ## 5.7.0-next.8
16
+
17
+ ### Minor Changes
18
+
19
+ - 6e14850: Added FOS download bridge method
20
+
21
+ ## 5.7.0-next.7
22
+
23
+ ### Minor Changes
24
+
25
+ - be6eab0: Add OS upload bridge method
26
+
27
+ ## 5.6.1-next.6
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies [fae0e71]
11
32
  - Updated dependencies [4718346]
12
- - Updated dependencies [94243f1]
13
- - Updated dependencies [0ef937d]
14
- - Updated dependencies [dcd46a4]
15
- - @forge/manifest@10.8.0-next.4-experimental-44e92a2
16
- - @forge/resolver@1.7.1-next.0-experimental-44e92a2
33
+ - @forge/manifest@10.8.0-next.5
17
34
 
18
35
  ## 5.6.1-next.5
19
36
 
@@ -0,0 +1,5 @@
1
+ export declare const deleteObjects: ({ functionKey, keys }: {
2
+ functionKey: string;
3
+ keys: string[];
4
+ }) => Promise<void>;
5
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../src/object-store/delete.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa;iBAAgD,MAAM;UAAQ,MAAM,EAAE;MAAK,QAAQ,IAAI,CAchH,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteObjects = void 0;
4
+ const invoke_1 = require("../invoke");
5
+ const errors_1 = require("../errors");
6
+ const deleteObjects = async ({ functionKey, keys }) => {
7
+ if (!functionKey || functionKey.length === 0) {
8
+ throw new errors_1.BridgeAPIError('functionKey is required to delete objects');
9
+ }
10
+ if (!Array.isArray(keys) || keys.length === 0) {
11
+ throw new errors_1.BridgeAPIError('keys array is required and must not be empty');
12
+ }
13
+ await Promise.all(keys.map(async (key) => {
14
+ await (0, invoke_1.invoke)(functionKey, { key });
15
+ }));
16
+ };
17
+ exports.deleteObjects = deleteObjects;
@@ -0,0 +1,6 @@
1
+ import type { DownloadResult } from './types';
2
+ export declare const download: ({ functionKey, keys }: {
3
+ functionKey: string;
4
+ keys: string[];
5
+ }) => Promise<DownloadResult[]>;
6
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/object-store/download.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAsB,MAAM,SAAS,CAAC;AAUlE,eAAO,MAAM,QAAQ;iBAIN,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,cAAc,EAAE,CAqD3B,CAAC"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.download = void 0;
4
+ const invoke_1 = require("../invoke");
5
+ const errors_1 = require("../errors");
6
+ const download = async ({ functionKey, keys }) => {
7
+ if (!functionKey || functionKey.length === 0) {
8
+ throw new errors_1.BridgeAPIError('functionKey is required to filter and generate download URLs');
9
+ }
10
+ if (!Array.isArray(keys) || keys.length === 0) {
11
+ throw new errors_1.BridgeAPIError('keys array is required and must not be empty');
12
+ }
13
+ const downloadUrlsTokeys = (await (0, invoke_1.invoke)(functionKey, {
14
+ keys
15
+ }));
16
+ if (!downloadUrlsTokeys || typeof downloadUrlsTokeys !== 'object') {
17
+ throw new errors_1.BridgeAPIError('Invalid response from functionKey');
18
+ }
19
+ const downloadPromises = Object.entries(downloadUrlsTokeys).map(async ([downloadUrl, key]) => {
20
+ try {
21
+ const response = await fetch(downloadUrl, {
22
+ method: 'GET'
23
+ });
24
+ if (!response.ok) {
25
+ return {
26
+ success: false,
27
+ key: key,
28
+ status: response.status,
29
+ error: `Download failed with status ${response.status}`
30
+ };
31
+ }
32
+ const blob = await response.blob();
33
+ return {
34
+ success: true,
35
+ key: key,
36
+ blob,
37
+ status: response.status
38
+ };
39
+ }
40
+ catch (error) {
41
+ return {
42
+ success: false,
43
+ key: key,
44
+ status: 503,
45
+ error: error instanceof Error ? error.message : 'Download failed'
46
+ };
47
+ }
48
+ });
49
+ const results = await Promise.all(downloadPromises);
50
+ return results;
51
+ };
52
+ exports.download = download;
@@ -0,0 +1,6 @@
1
+ import type { GetMetadataResult } from './types';
2
+ export declare const getMetadata: ({ functionKey, keys }: {
3
+ functionKey: string;
4
+ keys: string[];
5
+ }) => Promise<GetMetadataResult[]>;
6
+ //# sourceMappingURL=getMetadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMetadata.d.ts","sourceRoot":"","sources":["../../src/object-store/getMetadata.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAUjD,eAAO,MAAM,WAAW;iBAIT,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,iBAAiB,EAAE,CAyB9B,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMetadata = void 0;
4
+ const invoke_1 = require("../invoke");
5
+ const errors_1 = require("../errors");
6
+ const getMetadata = async ({ functionKey, keys }) => {
7
+ if (!functionKey || functionKey.length === 0) {
8
+ throw new errors_1.BridgeAPIError('functionKey is required to filter and generate object metadata');
9
+ }
10
+ if (!Array.isArray(keys) || keys.length === 0) {
11
+ throw new errors_1.BridgeAPIError('keys array is required and must not be empty');
12
+ }
13
+ const results = await Promise.all(keys.map(async (key) => {
14
+ const result = (await (0, invoke_1.invoke)(functionKey, { key }));
15
+ if (!result || typeof result !== 'object') {
16
+ return {
17
+ key: key,
18
+ error: 'Invalid response from functionKey'
19
+ };
20
+ }
21
+ return result;
22
+ }));
23
+ return results;
24
+ };
25
+ exports.getMetadata = getMetadata;
@@ -0,0 +1,38 @@
1
+ export declare type ObjectMetadata = {
2
+ length: number;
3
+ checksum: string;
4
+ checksumType: string;
5
+ };
6
+ export declare type FileMetadata = ObjectMetadata & {
7
+ key: string;
8
+ ttlSeconds?: number;
9
+ overwrite?: boolean;
10
+ };
11
+ export declare type UploadResult = {
12
+ success: boolean;
13
+ key: string;
14
+ status?: number;
15
+ error?: string;
16
+ };
17
+ export declare type DownloadResult = {
18
+ success: boolean;
19
+ key: string;
20
+ blob?: Blob;
21
+ status?: number;
22
+ error?: string;
23
+ };
24
+ export declare type PresignedURLMapping = {
25
+ [url: string]: FileMetadata;
26
+ };
27
+ export declare type DownloadURLMapping = {
28
+ [url: string]: string;
29
+ };
30
+ export declare type GetMetadataResult = {
31
+ key: string;
32
+ checksum?: string;
33
+ size?: number;
34
+ createdAt?: string;
35
+ currentVersion?: string;
36
+ error?: string;
37
+ };
38
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/object-store/types.ts"],"names":[],"mappings":"AAAA,oBAAY,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,oBAAY,YAAY,GAAG,cAAc,GAAG;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,oBAAY,cAAc,GAAG;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,oBAAY,mBAAmB,GAAG;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC;CAC7B,CAAC;AAEF,oBAAY,kBAAkB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAE3D,oBAAY,iBAAiB,GAAG;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ import type { UploadResult } from './types';
2
+ export declare const upload: ({ functionKey, objects }: {
3
+ functionKey: string;
4
+ objects: Blob[];
5
+ }) => Promise<UploadResult[]>;
6
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/object-store/upload.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuC,YAAY,EAAE,MAAM,SAAS,CAAC;AA8BjF,eAAO,MAAM,MAAM;iBAIJ,MAAM;aACV,IAAI,EAAE;MACb,QAAQ,YAAY,EAAE,CAkEzB,CAAC"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.upload = void 0;
4
+ const invoke_1 = require("../invoke");
5
+ const errors_1 = require("../errors");
6
+ const getObjectMetadata = async (blob) => {
7
+ const length = blob.size;
8
+ const arrayBuffer = await blob.arrayBuffer();
9
+ const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
10
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
11
+ const checksum = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
12
+ const checksumType = 'SHA-256';
13
+ return {
14
+ length,
15
+ checksum,
16
+ checksumType
17
+ };
18
+ };
19
+ const upload = async ({ functionKey, objects }) => {
20
+ if (!functionKey || functionKey.length === 0) {
21
+ throw new errors_1.BridgeAPIError('functionKey is required to filter and generate presigned URLs');
22
+ }
23
+ if (!Array.isArray(objects) || objects.length === 0) {
24
+ throw new errors_1.BridgeAPIError('objects array is required and must not be empty');
25
+ }
26
+ const allObjectMetadata = await Promise.all(objects.map((obj) => getObjectMetadata(obj)));
27
+ const presignedURLsToObjectMetadata = (await (0, invoke_1.invoke)(functionKey, {
28
+ allObjectMetadata
29
+ }));
30
+ if (!presignedURLsToObjectMetadata || typeof presignedURLsToObjectMetadata !== 'object') {
31
+ throw new errors_1.BridgeAPIError('Invalid response from functionKey');
32
+ }
33
+ const checksumToBlobMap = new Map();
34
+ objects.forEach((blob, index) => {
35
+ const metadata = allObjectMetadata[index];
36
+ checksumToBlobMap.set(metadata.checksum, blob);
37
+ });
38
+ const uploadPromises = Object.entries(presignedURLsToObjectMetadata).map(async ([presignedUrl, metadata]) => {
39
+ const { key, length, checksum } = metadata;
40
+ const object = checksumToBlobMap.get(checksum);
41
+ if (!object) {
42
+ return {
43
+ success: false,
44
+ key: key,
45
+ error: `Blob not found for checksum ${checksum}`
46
+ };
47
+ }
48
+ try {
49
+ const response = await fetch(presignedUrl, {
50
+ method: 'PUT',
51
+ body: object,
52
+ headers: {
53
+ 'Content-Type': object.type || 'application/octet-stream',
54
+ 'Content-Length': length.toString()
55
+ }
56
+ });
57
+ return {
58
+ success: response.ok,
59
+ key: key,
60
+ status: response.status,
61
+ error: response.ok ? undefined : `Upload failed with status ${response.status}`
62
+ };
63
+ }
64
+ catch (error) {
65
+ return {
66
+ success: false,
67
+ key: key,
68
+ status: 503,
69
+ error: error instanceof Error ? error.message : 'Upload failed'
70
+ };
71
+ }
72
+ });
73
+ const results = await Promise.all(uploadPromises);
74
+ return results;
75
+ };
76
+ exports.upload = upload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/bridge",
3
- "version": "5.6.1-next.5-experimental-44e92a2",
3
+ "version": "5.7.0-next.10",
4
4
  "description": "Forge bridge API for custom UI apps",
5
5
  "author": "Atlassian",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -15,10 +15,10 @@
15
15
  "dependencies": {
16
16
  "@atlaskit/tokens": "^1.58.0",
17
17
  "@forge/i18n": "0.0.7",
18
- "@forge/resolver": "1.7.1-next.0-experimental-44e92a2",
18
+ "@forge/resolver": "1.7.1-next.0",
19
19
  "@statsig/js-client": "3.18.2",
20
20
  "@types/history": "^4.7.11",
21
- "@forge/manifest": "10.8.0-next.4-experimental-44e92a2"
21
+ "@forge/manifest": "10.8.0-next.5"
22
22
  },
23
23
  "devDependencies": {
24
24
  "history": "5.3.0",