@forge/bridge 5.8.0-next.12-experimental-f85d28a → 5.8.0-next.14

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,26 +1,23 @@
1
1
  # @forge/bridge
2
2
 
3
- ## 5.8.0-next.12-experimental-f85d28a
3
+ ## 5.8.0-next.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 31ea34b: block prod apps from using object store bridge methods
8
+ - 5fe2092: Remove rovo bridge method for now
9
+
10
+ ## 5.8.0-next.13
4
11
 
5
12
  ### Minor Changes
6
13
 
7
- - 1d129f0: Allow objects in event payloads. The object must be JSON-serializable.
8
- - 08fbb0a: Add rovo.open bridge method that opens rovo chat
9
- - 617c3d9: Add base64 support to upload bridge method
10
- - a4bccb7: Export FOS bridge methods and fixing bugs
14
+ - f23a84e: Add useObjectStore hook
11
15
 
12
16
  ### Patch Changes
13
17
 
14
- - fe20eb0: Changing export names
15
- - Updated dependencies [0a3f5d5]
16
- - Updated dependencies [9a6d346]
17
- - Updated dependencies [260eb24]
18
- - Updated dependencies [3228cf0]
19
- - Updated dependencies [8962080]
20
- - Updated dependencies [f0a5a03]
21
- - Updated dependencies [d00ef59]
22
- - Updated dependencies [78efec7]
23
- - @forge/manifest@11.0.0-next.7-experimental-f85d28a
18
+ - Updated dependencies [24bd686]
19
+ - Updated dependencies [2011ffe]
20
+ - @forge/manifest@11.0.0-next.8
24
21
 
25
22
  ## 5.8.0-next.12
26
23
 
@@ -1 +1 @@
1
- {"version":3,"file":"deleteObjects.d.ts","sourceRoot":"","sources":["../../src/object-store/deleteObjects.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,aAAa;iBAAgD,MAAM;UAAQ,MAAM,EAAE;MAAK,QAAQ,IAAI,CAchH,CAAC"}
1
+ {"version":3,"file":"deleteObjects.d.ts","sourceRoot":"","sources":["../../src/object-store/deleteObjects.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,aAAa;iBAAgD,MAAM;UAAQ,MAAM,EAAE;MAAK,QAAQ,IAAI,CAgBhH,CAAC"}
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deleteObjects = void 0;
4
4
  const invoke_1 = require("../invoke");
5
5
  const errors_1 = require("../errors");
6
+ const utils_1 = require("./utils");
6
7
  const deleteObjects = async ({ functionKey, keys }) => {
8
+ await (0, utils_1.checkRestrictedEnvironment)();
7
9
  if (!functionKey || functionKey.length === 0) {
8
10
  throw new errors_1.BridgeAPIError('functionKey is required to delete objects');
9
11
  }
@@ -1 +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"}
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;AAWlE,eAAO,MAAM,QAAQ;iBAIN,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,cAAc,EAAE,CAuD3B,CAAC"}
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.download = void 0;
4
4
  const invoke_1 = require("../invoke");
5
5
  const errors_1 = require("../errors");
6
+ const utils_1 = require("./utils");
6
7
  const download = async ({ functionKey, keys }) => {
8
+ await (0, utils_1.checkRestrictedEnvironment)();
7
9
  if (!functionKey || functionKey.length === 0) {
8
10
  throw new errors_1.BridgeAPIError('functionKey is required to filter and generate download URLs');
9
11
  }
@@ -1 +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"}
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;AAWjD,eAAO,MAAM,WAAW;iBAIT,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,iBAAiB,EAAE,CA2B9B,CAAC"}
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getMetadata = void 0;
4
4
  const index_1 = require("../invoke/index");
5
5
  const errors_1 = require("../errors");
6
+ const utils_1 = require("./utils");
6
7
  const getMetadata = async ({ functionKey, keys }) => {
8
+ await (0, utils_1.checkRestrictedEnvironment)();
7
9
  if (!functionKey || functionKey.length === 0) {
8
10
  throw new errors_1.BridgeAPIError('functionKey is required to filter and generate object metadata');
9
11
  }
@@ -1,2 +1,3 @@
1
1
  export * from './objectStore';
2
+ export * from './types';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/object-store/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/object-store/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC"}
@@ -2,3 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./objectStore"), exports);
5
+ tslib_1.__exportStar(require("./types"), exports);
@@ -1,3 +1,4 @@
1
+ import { createUploadPromises } from './upload';
1
2
  export declare const objectStore: {
2
3
  upload: ({ functionKey, objects }: {
3
4
  functionKey: string;
@@ -16,4 +17,5 @@ export declare const objectStore: {
16
17
  keys: string[];
17
18
  }) => Promise<void>;
18
19
  };
20
+ export { createUploadPromises };
19
21
  //# sourceMappingURL=objectStore.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"objectStore.d.ts","sourceRoot":"","sources":["../../src/object-store/objectStore.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;CAKvB,CAAC"}
1
+ {"version":3,"file":"objectStore.d.ts","sourceRoot":"","sources":["../../src/object-store/objectStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAKxD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;CAKvB,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.objectStore = void 0;
3
+ exports.createUploadPromises = exports.objectStore = void 0;
4
4
  const upload_1 = require("./upload");
5
+ Object.defineProperty(exports, "createUploadPromises", { enumerable: true, get: function () { return upload_1.createUploadPromises; } });
5
6
  const deleteObjects_1 = require("./deleteObjects");
6
7
  const download_1 = require("./download");
7
8
  const getMetadata_1 = require("./getMetadata");
@@ -6,6 +6,7 @@ export declare type ObjectMetadata = {
6
6
  export declare type Base64Object = {
7
7
  data: string;
8
8
  mimeType?: string;
9
+ fileSize?: number;
9
10
  };
10
11
  export declare type UploadObject = Blob | Base64Object;
11
12
  export declare type FileMetadata = ObjectMetadata & {
@@ -19,6 +20,12 @@ export declare type UploadResult = {
19
20
  status?: number;
20
21
  error?: string;
21
22
  };
23
+ export declare type UploadPromiseItem = {
24
+ promise: Promise<UploadResult>;
25
+ index: number;
26
+ objectType?: string;
27
+ objectSize?: number;
28
+ };
22
29
  export declare type DownloadResult = {
23
30
  success: boolean;
24
31
  key: string;
@@ -40,4 +47,5 @@ export declare type GetMetadataResult = {
40
47
  currentVersion?: string;
41
48
  error?: string;
42
49
  };
50
+ export declare const BRIDGE_OBJECT_STORE_RESTRICTED_ENVIRONMENT_ERROR = "Object Store bridge methods are restricted to Forge apps in a non-production environment. For more information please see https://developer.atlassian.com/platform/forge/cli-reference/environments/ for reference on Forge app environments.";
43
51
  //# sourceMappingURL=types.d.ts.map
@@ -1 +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;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,oBAAY,YAAY,GAAG,IAAI,GAAG,YAAY,CAAC;AAE/C,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"}
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;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,oBAAY,YAAY,GAAG,IAAI,GAAG,YAAY,CAAC;AAE/C,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,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,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;AAEF,eAAO,MAAM,gDAAgD,kPACoL,CAAC"}
@@ -1,2 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BRIDGE_OBJECT_STORE_RESTRICTED_ENVIRONMENT_ERROR = void 0;
4
+ exports.BRIDGE_OBJECT_STORE_RESTRICTED_ENVIRONMENT_ERROR = 'Object Store bridge methods are restricted to Forge apps in a non-production environment. For more information please see https://developer.atlassian.com/platform/forge/cli-reference/environments/ for reference on Forge app environments.';
@@ -1,4 +1,8 @@
1
- import type { UploadResult, UploadObject } from './types';
1
+ import type { UploadResult, UploadObject, UploadPromiseItem } from './types';
2
+ export declare const createUploadPromises: ({ functionKey, objects }: {
3
+ functionKey: string;
4
+ objects: UploadObject[];
5
+ }) => Promise<UploadPromiseItem[]>;
2
6
  export declare const upload: ({ functionKey, objects }: {
3
7
  functionKey: string;
4
8
  objects: UploadObject[];
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/object-store/upload.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuC,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA4C/F,eAAO,MAAM,MAAM;iBAIJ,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,YAAY,EAAE,CAuFzB,CAAC"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/object-store/upload.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuC,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AA8ClH,eAAO,MAAM,oBAAoB;iBAIlB,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,iBAAiB,EAAE,CA4G9B,CAAC;AAUF,eAAO,MAAM,MAAM;iBAIJ,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,YAAY,EAAE,CAIzB,CAAC"}
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.upload = void 0;
3
+ exports.upload = exports.createUploadPromises = void 0;
4
4
  const invoke_1 = require("../invoke");
5
5
  const errors_1 = require("../errors");
6
+ const utils_1 = require("./utils");
6
7
  const base64ToBlob = (base64, mimeType) => {
7
8
  const byteCharacters = atob(base64);
8
9
  const byteNumbers = new Array(byteCharacters.length);
@@ -25,7 +26,8 @@ const getObjectMetadata = async (blob) => {
25
26
  checksumType
26
27
  };
27
28
  };
28
- const upload = async ({ functionKey, objects }) => {
29
+ const createUploadPromises = async ({ functionKey, objects }) => {
30
+ await (0, utils_1.checkRestrictedEnvironment)();
29
31
  if (!functionKey || functionKey.length === 0) {
30
32
  throw new errors_1.BridgeAPIError('functionKey is required to filter and generate presigned URLs');
31
33
  }
@@ -55,46 +57,70 @@ const upload = async ({ functionKey, objects }) => {
55
57
  throw new errors_1.BridgeAPIError('Invalid response from functionKey');
56
58
  }
57
59
  const checksumToBlobMap = new Map();
60
+ const checksumToIndexMap = new Map();
58
61
  blobs.forEach((blob, index) => {
59
62
  const metadata = allObjectMetadata[index];
60
63
  checksumToBlobMap.set(metadata.checksum, blob);
64
+ checksumToIndexMap.set(metadata.checksum, index);
61
65
  });
62
- const uploadPromises = Object.entries(presignedURLsToObjectMetadata).map(async ([presignedUrl, metadata]) => {
63
- const { key, length, checksum } = metadata;
66
+ const uploadPromises = Object.entries(presignedURLsToObjectMetadata).map(([presignedUrl, metadata]) => {
67
+ const { key, checksum } = metadata;
64
68
  const object = checksumToBlobMap.get(checksum);
65
- if (!object) {
69
+ const index = checksumToIndexMap.get(checksum);
70
+ if (index === undefined) {
66
71
  return {
67
- success: false,
68
- key: key,
69
- error: `Blob not found for checksum ${checksum}`
72
+ promise: Promise.resolve({
73
+ success: false,
74
+ key: key,
75
+ error: `Index not found for checksum ${checksum}`
76
+ }),
77
+ index: -1
70
78
  };
71
79
  }
72
- try {
73
- const response = await fetch(presignedUrl, {
74
- method: 'PUT',
75
- body: object,
76
- headers: {
77
- 'Content-Type': object.type || 'application/octet-stream',
78
- 'Content-Length': length.toString()
79
- }
80
- });
81
- return {
82
- success: response.ok,
83
- key: key,
84
- status: response.status,
85
- error: response.ok ? undefined : `Upload failed with status ${response.status}`
86
- };
87
- }
88
- catch (error) {
80
+ if (!object) {
89
81
  return {
90
- success: false,
91
- key: key,
92
- status: 503,
93
- error: error instanceof Error ? error.message : 'Upload failed'
82
+ promise: Promise.resolve({
83
+ success: false,
84
+ key: key,
85
+ error: `Blob not found for checksum ${checksum}`
86
+ }),
87
+ index
94
88
  };
95
89
  }
90
+ const uploadPromise = (async () => {
91
+ try {
92
+ const response = await fetch(presignedUrl, {
93
+ method: 'PUT',
94
+ body: object,
95
+ headers: {
96
+ 'Content-Type': object.type || 'application/octet-stream',
97
+ 'Content-Length': object.size.toString()
98
+ }
99
+ });
100
+ return {
101
+ success: response.ok,
102
+ key: key,
103
+ status: response.status,
104
+ error: response.ok ? undefined : `Upload failed with status ${response.status}`
105
+ };
106
+ }
107
+ catch (error) {
108
+ return {
109
+ success: false,
110
+ key: key,
111
+ status: 503,
112
+ error: error instanceof Error ? error.message : 'Upload failed'
113
+ };
114
+ }
115
+ })();
116
+ return { promise: uploadPromise, index, objectType: object.type, objectSize: object.size };
96
117
  });
97
- const results = await Promise.all(uploadPromises);
118
+ return uploadPromises;
119
+ };
120
+ exports.createUploadPromises = createUploadPromises;
121
+ const upload = async ({ functionKey, objects }) => {
122
+ const uploadPromises = await (0, exports.createUploadPromises)({ functionKey, objects });
123
+ const results = await Promise.all(uploadPromises.map((item) => item.promise));
98
124
  return results;
99
125
  };
100
126
  exports.upload = upload;
@@ -0,0 +1,2 @@
1
+ export declare const checkRestrictedEnvironment: () => Promise<void>;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/object-store/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,0BAA0B,QAAa,QAAQ,IAAI,CAK/D,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkRestrictedEnvironment = void 0;
4
+ const errors_1 = require("../errors");
5
+ const view_1 = require("../view");
6
+ const types_1 = require("./types");
7
+ const checkRestrictedEnvironment = async () => {
8
+ const { environmentType } = await view_1.view.getContext();
9
+ if (environmentType === 'PRODUCTION') {
10
+ throw new errors_1.BridgeAPIError(types_1.BRIDGE_OBJECT_STORE_RESTRICTED_ENVIRONMENT_ERROR);
11
+ }
12
+ };
13
+ exports.checkRestrictedEnvironment = checkRestrictedEnvironment;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/bridge",
3
- "version": "5.8.0-next.12-experimental-f85d28a",
3
+ "version": "5.8.0-next.14",
4
4
  "description": "Forge bridge API for custom UI apps",
5
5
  "author": "Atlassian",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
@@ -18,7 +18,7 @@
18
18
  "@forge/resolver": "1.7.1",
19
19
  "@statsig/js-client": "3.18.2",
20
20
  "@types/history": "^4.7.11",
21
- "@forge/manifest": "11.0.0-next.7-experimental-f85d28a"
21
+ "@forge/manifest": "11.0.0-next.8"
22
22
  },
23
23
  "devDependencies": {
24
24
  "history": "5.3.0",