@forge/bridge 5.15.2-next.0 → 5.16.0-experimental-a6c6519
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 +63 -0
- package/out/events/serialiseBlob.js +11 -0
- package/out/featureFlags/evaluator.js +11 -2
- package/out/featureFlags/featureFlags.d.ts +9 -0
- package/out/featureFlags/featureFlags.d.ts.map +1 -1
- package/out/featureFlags/featureFlags.js +9 -0
- package/out/fetch/fetch.js +12 -0
- package/out/flag/flag.d.ts +7 -0
- package/out/flag/flag.d.ts.map +1 -1
- package/out/i18n/index.d.ts +15 -0
- package/out/i18n/index.d.ts.map +1 -1
- package/out/i18n/index.js +7 -0
- package/out/invoke/invoke.d.ts +25 -2
- package/out/invoke/invoke.d.ts.map +1 -1
- package/out/invoke/invoke.js +14 -2
- package/out/modal/modal.js +1 -0
- package/out/object-store/deleteObjects.d.ts +8 -0
- package/out/object-store/deleteObjects.d.ts.map +1 -1
- package/out/object-store/deleteObjects.js +8 -0
- package/out/object-store/download.d.ts +8 -0
- package/out/object-store/download.d.ts.map +1 -1
- package/out/object-store/download.js +8 -0
- package/out/object-store/getMetadata.d.ts +8 -0
- package/out/object-store/getMetadata.d.ts.map +1 -1
- package/out/object-store/getMetadata.js +8 -0
- package/out/object-store/upload.d.ts +17 -0
- package/out/object-store/upload.d.ts.map +1 -1
- package/out/object-store/upload.js +26 -0
- package/out/permissions/permissionsUtil.d.ts +51 -0
- package/out/permissions/permissionsUtil.d.ts.map +1 -1
- package/out/permissions/permissionsUtil.js +52 -0
- package/out/realtime/productContext.js +2 -0
- package/out/router/router.js +23 -0
- package/out/router/targets.d.ts +27 -0
- package/out/router/targets.d.ts.map +1 -1
- package/out/router/targets.js +28 -0
- package/out/rovo/isEnabled.d.ts +5 -0
- package/out/rovo/isEnabled.d.ts.map +1 -1
- package/out/rovo/isEnabled.js +5 -0
- package/out/rovo/open.d.ts +9 -0
- package/out/rovo/open.d.ts.map +1 -1
- package/out/rovo/open.js +9 -0
- package/out/types.d.ts +6 -0
- package/out/types.d.ts.map +1 -1
- package/out/view/close.js +1 -0
- package/out/view/emitReadyEvent.js +5 -0
- package/out/view/getContext.js +2 -0
- package/out/view/open.js +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# @forge/bridge
|
|
2
2
|
|
|
3
|
+
## 5.16.0-experimental-a6c6519
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [5b726e6]
|
|
8
|
+
- @forge/manifest@12.6.0-experimental-a6c6519
|
|
9
|
+
|
|
10
|
+
## 5.16.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- fd8e87e: Add payload generic and jsdoc to invoke
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [8b7704f]
|
|
19
|
+
- Updated dependencies [4964a50]
|
|
20
|
+
- Updated dependencies [6b848cf]
|
|
21
|
+
- Updated dependencies [911bef1]
|
|
22
|
+
- Updated dependencies [399ae7d]
|
|
23
|
+
- Updated dependencies [955c1ab]
|
|
24
|
+
- Updated dependencies [53b24df]
|
|
25
|
+
- Updated dependencies [36fbb18]
|
|
26
|
+
- Updated dependencies [3b625c7]
|
|
27
|
+
- @forge/manifest@12.6.0
|
|
28
|
+
- @forge/resolver@1.8.0
|
|
29
|
+
|
|
30
|
+
## 5.16.0-next.4
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [3b625c7]
|
|
35
|
+
- @forge/manifest@12.6.0-next.3
|
|
36
|
+
|
|
37
|
+
## 5.16.0-next.3
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- Updated dependencies [8b7704f]
|
|
42
|
+
- Updated dependencies [4964a50]
|
|
43
|
+
- Updated dependencies [911bef1]
|
|
44
|
+
- Updated dependencies [955c1ab]
|
|
45
|
+
- Updated dependencies [53b24df]
|
|
46
|
+
- @forge/manifest@12.6.0-next.2
|
|
47
|
+
|
|
48
|
+
## 5.16.0-next.2
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Updated dependencies [36fbb18]
|
|
53
|
+
- @forge/manifest@12.6.0-next.1
|
|
54
|
+
|
|
55
|
+
## 5.16.0-next.1
|
|
56
|
+
|
|
57
|
+
### Minor Changes
|
|
58
|
+
|
|
59
|
+
- fd8e87e: Add payload generic and jsdoc to invoke
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies [6b848cf]
|
|
64
|
+
- @forge/resolver@1.8.0-next.0
|
|
65
|
+
|
|
3
66
|
## 5.15.2-next.0
|
|
4
67
|
|
|
5
68
|
### Patch Changes
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.containsSerialisedBlobs = exports.containsBlobs = exports.deserialiseBlobsInPayload = exports.serialiseBlobsInPayload = void 0;
|
|
4
4
|
const blobParser_1 = require("../utils/blobParser");
|
|
5
|
+
// Copied from https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore?tab=readme-ov-file#_isplainobject
|
|
5
6
|
const isPlainObject = (value) => {
|
|
6
7
|
if (typeof value !== 'object' || value === null)
|
|
7
8
|
return false;
|
|
@@ -23,38 +24,48 @@ const blobToBase64WithMetadata = async (blob) => {
|
|
|
23
24
|
};
|
|
24
25
|
};
|
|
25
26
|
const base64WithMetadataToBlob = (metadata) => {
|
|
27
|
+
// typecasting as Blob since base64ToBlob returns Blob | null but this is only null if data is undefined which it won't be here
|
|
26
28
|
return (0, blobParser_1.base64ToBlob)(metadata.data, metadata.type);
|
|
27
29
|
};
|
|
30
|
+
// Recursively converts all Blobs in an object or array to base64 with metadata
|
|
28
31
|
const serialiseBlobsInPayload = async (payload) => {
|
|
29
32
|
if (payload instanceof Blob) {
|
|
33
|
+
// Convert blob to base64 with metadata and mark it as a serialized blob
|
|
30
34
|
const blobData = await blobToBase64WithMetadata(payload);
|
|
31
35
|
return {
|
|
32
36
|
...blobData,
|
|
37
|
+
// Custom property used to identify serialized blob data for deserialization
|
|
33
38
|
__isBlobData: true
|
|
34
39
|
};
|
|
35
40
|
}
|
|
36
41
|
if (Array.isArray(payload)) {
|
|
42
|
+
// Recursively process array elements
|
|
37
43
|
return Promise.all(payload.map((item) => (0, exports.serialiseBlobsInPayload)(item)));
|
|
38
44
|
}
|
|
39
45
|
if (payload && isPlainObject(payload)) {
|
|
46
|
+
// Recursively process object properties
|
|
40
47
|
const entries = await Promise.all(Object.entries(payload).map(async ([key, value]) => [key, await (0, exports.serialiseBlobsInPayload)(value)]));
|
|
41
48
|
return Object.fromEntries(entries);
|
|
42
49
|
}
|
|
43
50
|
return payload;
|
|
44
51
|
};
|
|
45
52
|
exports.serialiseBlobsInPayload = serialiseBlobsInPayload;
|
|
53
|
+
// Recursively converts all serialized blob data back to Blobs in an object or array
|
|
46
54
|
const deserialiseBlobsInPayload = (payload) => {
|
|
47
55
|
if (payload && isPlainObject(payload) && '__isBlobData' in payload) {
|
|
48
56
|
const typedData = payload;
|
|
57
|
+
// Convert serialized blob data back to Blob
|
|
49
58
|
return base64WithMetadataToBlob({
|
|
50
59
|
data: typedData.data,
|
|
51
60
|
type: typedData.type
|
|
52
61
|
});
|
|
53
62
|
}
|
|
54
63
|
if (Array.isArray(payload)) {
|
|
64
|
+
// Recursively process array elements
|
|
55
65
|
return payload.map((item) => (0, exports.deserialiseBlobsInPayload)(item));
|
|
56
66
|
}
|
|
57
67
|
if (payload && isPlainObject(payload)) {
|
|
68
|
+
// Recursively process object properties
|
|
58
69
|
const result = {};
|
|
59
70
|
for (const [key, value] of Object.entries(payload)) {
|
|
60
71
|
result[key] = (0, exports.deserialiseBlobsInPayload)(value);
|
|
@@ -7,6 +7,7 @@ class Evaluator {
|
|
|
7
7
|
}
|
|
8
8
|
checkFlag(flagName, defaultValue) {
|
|
9
9
|
if (!this.results || !this.results.feature_flags) {
|
|
10
|
+
// fallback to default value
|
|
10
11
|
return defaultValue;
|
|
11
12
|
}
|
|
12
13
|
const featureFlags = this.results.feature_flags;
|
|
@@ -15,7 +16,9 @@ class Evaluator {
|
|
|
15
16
|
hashedValue = this.getHashedValue(flagName);
|
|
16
17
|
}
|
|
17
18
|
catch (err) {
|
|
19
|
+
// eslint-disable-next-line no-console
|
|
18
20
|
console.error('Unexpected error occurred while evaluating flag ', err);
|
|
21
|
+
// If hashing fails for any reason, do not throw; safely return default
|
|
19
22
|
return defaultValue;
|
|
20
23
|
}
|
|
21
24
|
if (!hashedValue) {
|
|
@@ -23,17 +26,21 @@ class Evaluator {
|
|
|
23
26
|
}
|
|
24
27
|
const evaluatedFlag = featureFlags[hashedValue];
|
|
25
28
|
if (evaluatedFlag) {
|
|
29
|
+
// if flag being checked is disabled
|
|
26
30
|
if (evaluatedFlag.disabled) {
|
|
27
31
|
return false;
|
|
28
32
|
}
|
|
29
33
|
return evaluatedFlag.value;
|
|
30
34
|
}
|
|
35
|
+
// fallback to default value
|
|
31
36
|
return defaultValue;
|
|
32
37
|
}
|
|
33
38
|
shutDown() {
|
|
34
39
|
this.results = undefined;
|
|
35
40
|
}
|
|
41
|
+
// To be Updated with proper hashing function
|
|
36
42
|
getHashedValue(flagName) {
|
|
43
|
+
// Defensive: ensure stable, non-throwing behavior for unexpected inputs
|
|
37
44
|
if (typeof flagName !== 'string') {
|
|
38
45
|
return '';
|
|
39
46
|
}
|
|
@@ -41,12 +48,14 @@ class Evaluator {
|
|
|
41
48
|
if (input.length === 0) {
|
|
42
49
|
return '';
|
|
43
50
|
}
|
|
51
|
+
// djb2 hashing (unsigned 32-bit), matches server-side encoding
|
|
44
52
|
let hash = 5381;
|
|
45
53
|
for (let i = 0; i < input.length; i += 1) {
|
|
46
54
|
const charCode = input.charCodeAt(i);
|
|
47
|
-
hash = (hash << 5) + hash + charCode;
|
|
48
|
-
hash |= 0;
|
|
55
|
+
hash = (hash << 5) + hash + charCode; // hash * 33 + c
|
|
56
|
+
hash |= 0; // force 32-bit signed int
|
|
49
57
|
}
|
|
58
|
+
// Convert to unsigned 32-bit and return as a decimal string
|
|
50
59
|
return (hash >>> 0).toString();
|
|
51
60
|
}
|
|
52
61
|
}
|
|
@@ -3,8 +3,17 @@ export declare class FeatureFlags {
|
|
|
3
3
|
private initialized;
|
|
4
4
|
private evaluator;
|
|
5
5
|
private eventProps;
|
|
6
|
+
/**
|
|
7
|
+
* Initialize the feature flags client
|
|
8
|
+
*/
|
|
6
9
|
initialize(user: FeatureFlagUser, config?: ForgeFeatureFlagConfig): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Check if a feature flag is enabled for the user
|
|
12
|
+
*/
|
|
7
13
|
checkFlag(flagName: string, defaultValue?: boolean): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Shutdown the feature flags client
|
|
16
|
+
*/
|
|
8
17
|
shutdown(): void;
|
|
9
18
|
isInitialized(): boolean;
|
|
10
19
|
private sendCheckFlagEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"featureFlags.d.ts","sourceRoot":"","sources":["../../src/featureFlags/featureFlags.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,eAAe,EACf,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAEjB,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,UAAU,CAAkC;
|
|
1
|
+
{"version":3,"file":"featureFlags.d.ts","sourceRoot":"","sources":["../../src/featureFlags/featureFlags.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,eAAe,EACf,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAEjB,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,UAAU,CAAkC;IAEpD;;OAEG;IACU,UAAU,CACrB,IAAI,EAAE,eAAe,EACrB,MAAM,GAAE,sBAAuD,GAC9D,OAAO,CAAC,IAAI,CAAC;IAiBhB;;OAEG;IACI,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,OAAO;IAUjE;;OAEG;IACI,QAAQ;IAQR,aAAa;IAIpB,OAAO,CAAC,kBAAkB;CAa3B"}
|
|
@@ -10,6 +10,9 @@ class FeatureFlags {
|
|
|
10
10
|
this.initialized = false;
|
|
11
11
|
this.eventProps = {};
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Initialize the feature flags client
|
|
15
|
+
*/
|
|
13
16
|
async initialize(user, config = { environment: 'development' }) {
|
|
14
17
|
if (this.isInitialized()) {
|
|
15
18
|
return;
|
|
@@ -22,6 +25,9 @@ class FeatureFlags {
|
|
|
22
25
|
this.initialized = true;
|
|
23
26
|
this.evaluator = new evaluator_1.Evaluator(result);
|
|
24
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if a feature flag is enabled for the user
|
|
30
|
+
*/
|
|
25
31
|
checkFlag(flagName, defaultValue = false) {
|
|
26
32
|
if (!this.isInitialized() || !this.evaluator) {
|
|
27
33
|
this.sendCheckFlagEvent(flagName, false);
|
|
@@ -30,6 +36,9 @@ class FeatureFlags {
|
|
|
30
36
|
this.sendCheckFlagEvent(flagName, true);
|
|
31
37
|
return this.evaluator.checkFlag(flagName, defaultValue);
|
|
32
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Shutdown the feature flags client
|
|
41
|
+
*/
|
|
33
42
|
shutdown() {
|
|
34
43
|
if (!this.isInitialized()) {
|
|
35
44
|
return;
|
package/out/fetch/fetch.js
CHANGED
|
@@ -5,11 +5,18 @@ const blobParser_1 = require("../utils/blobParser");
|
|
|
5
5
|
const parseFormData = async (form, matchFilePrefix = false) => {
|
|
6
6
|
const parsed = {};
|
|
7
7
|
for (const [key, value] of form.entries()) {
|
|
8
|
+
// Jira and Confluence REST APIs requires that the field containing
|
|
9
|
+
// the file MUST be named exactly 'file'
|
|
8
10
|
const isFileKey = matchFilePrefix ? key.startsWith('file') : key === 'file';
|
|
9
11
|
if (isFileKey) {
|
|
10
12
|
const fileName = value.name;
|
|
11
13
|
const fileType = value.type;
|
|
14
|
+
// we parse the file as a base64 string so it
|
|
15
|
+
// can be properly transfered over the bridge.
|
|
16
|
+
// we'll parse it back to Blob in the host product
|
|
12
17
|
parsed[key] = await (0, blobParser_1.blobToBase64)(value);
|
|
18
|
+
// we also need to pass the file name and type,
|
|
19
|
+
// as those will be lost in the base64 conversion
|
|
13
20
|
parsed[`__${key}Name`] = fileName;
|
|
14
21
|
parsed[`__${key}Type`] = fileType;
|
|
15
22
|
}
|
|
@@ -24,7 +31,9 @@ const validateFetchOptions = (init) => {
|
|
|
24
31
|
return init;
|
|
25
32
|
}
|
|
26
33
|
if ('signal' in init) {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
27
35
|
const { signal: _signal, ...rest } = init;
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
28
37
|
console.error('Signal is not supported in @forge/bridge and was removed from fetch options. Please use the fetch method from @forge/api for signal support.');
|
|
29
38
|
return rest;
|
|
30
39
|
}
|
|
@@ -34,6 +43,8 @@ const parseRequest = async (fetchType, init) => {
|
|
|
34
43
|
const isFormData = (init === null || init === void 0 ? void 0 : init.body) instanceof FormData ? true : false;
|
|
35
44
|
const requestBody = isFormData ? await parseFormData(init === null || init === void 0 ? void 0 : init.body, fetchType === 'remote') : init === null || init === void 0 ? void 0 : init.body;
|
|
36
45
|
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 });
|
|
46
|
+
// If `init.body` is a `FormData`, a `content-type` header required for the body to be parsed by the
|
|
47
|
+
// API receiving this request will be generated in req.headers.
|
|
37
48
|
const headers = Object.fromEntries(req.headers.entries());
|
|
38
49
|
const body = req.method !== 'GET' ? await req.text() : null;
|
|
39
50
|
return {
|
|
@@ -64,6 +75,7 @@ const productFetchApi = (callBridge) => {
|
|
|
64
75
|
const fetch = async (product, restPath, init) => {
|
|
65
76
|
const validatedInit = validateFetchOptions(init);
|
|
66
77
|
const { body: requestBody, headers: requestHeaders, isMultipartFormData } = await parseRequest('product', validatedInit);
|
|
78
|
+
// https://ecosystem.atlassian.net/browse/BUILD-1118 Skip xsrf check for oauth request
|
|
67
79
|
if (!requestHeaders.has('X-Atlassian-Token')) {
|
|
68
80
|
requestHeaders.set('X-Atlassian-Token', 'no-check');
|
|
69
81
|
}
|
package/out/flag/flag.d.ts
CHANGED
|
@@ -11,7 +11,14 @@ export interface FlagOptions {
|
|
|
11
11
|
id: number | string;
|
|
12
12
|
title?: string;
|
|
13
13
|
description?: string;
|
|
14
|
+
/**
|
|
15
|
+
* `type` is used to determine the icon of Flag.
|
|
16
|
+
* If `appearance` is given, `type` is overriden to equal `appearance`.
|
|
17
|
+
*/
|
|
14
18
|
type?: FlagType;
|
|
19
|
+
/**
|
|
20
|
+
* When `appearance` is given, the Flag is bold. If not, it's a normal Flag.
|
|
21
|
+
*/
|
|
15
22
|
appearance?: FlagAppearance;
|
|
16
23
|
actions?: FlagAction[];
|
|
17
24
|
isAutoDismiss?: boolean;
|
package/out/flag/flag.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flag.d.ts","sourceRoot":"","sources":["../../src/flag/flag.ts"],"names":[],"mappings":"AAGA,oBAAY,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AACtE,oBAAY,QAAQ,GAAG,cAAc,CAAC;AAEtC,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"flag.d.ts","sourceRoot":"","sources":["../../src/flag/flag.ts"],"names":[],"mappings":"AAGA,oBAAY,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AACtE,oBAAY,QAAQ,GAAG,cAAc,CAAC;AAEtC,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;OAEG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAID,eAAO,MAAM,QAAQ,YAAa,WAAW,KAAG,IAgB/C,CAAC"}
|
package/out/i18n/index.d.ts
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { type ForgeSupportedLocaleCode, type GetTranslationsOptions, type GetTranslationsResult } from '@forge/i18n';
|
|
2
2
|
export declare const resetTranslationsCache: () => void;
|
|
3
3
|
export declare const getTranslations: (locale?: ForgeSupportedLocaleCode | null, options?: GetTranslationsOptions) => Promise<GetTranslationsResult>;
|
|
4
|
+
/**
|
|
5
|
+
* A function that translates an i18n key to a string.
|
|
6
|
+
*
|
|
7
|
+
* @param i18nKey The i18n key to translate.
|
|
8
|
+
* @param defaultValue The default value to return if the i18n key is not found.
|
|
9
|
+
* If not provided, the i18n key is returned.
|
|
10
|
+
* @returns The translated string.
|
|
11
|
+
*/
|
|
4
12
|
export declare type TranslationFunction = (i18nKey: string, defaultValue?: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a translation function (i.e. `t`) for the given locale.
|
|
15
|
+
* If no locale is provided, the locale from the current view context is used.
|
|
16
|
+
*
|
|
17
|
+
* @param locale The locale to create the translation function for.
|
|
18
|
+
* @returns The translation function.
|
|
19
|
+
*/
|
|
5
20
|
export declare const createTranslationFunction: (locale?: ForgeSupportedLocaleCode | null) => Promise<TranslationFunction>;
|
|
6
21
|
//# sourceMappingURL=index.d.ts.map
|
package/out/i18n/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAM3B,MAAM,aAAa,CAAC;AAuBrB,eAAO,MAAM,sBAAsB,QAAO,IAEzC,CAAC;AAEF,eAAO,MAAM,eAAe,YAClB,wBAAwB,GAAG,IAAI,YAC9B,sBAAsB,KAG9B,QAAQ,qBAAqB,CAO/B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAM3B,MAAM,aAAa,CAAC;AAuBrB,eAAO,MAAM,sBAAsB,QAAO,IAEzC,CAAC;AAEF,eAAO,MAAM,eAAe,YAClB,wBAAwB,GAAG,IAAI,YAC9B,sBAAsB,KAG9B,QAAQ,qBAAqB,CAO/B,CAAC;AAEF;;;;;;;GAOG;AACH,oBAAY,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AAErF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,YAC5B,wBAAwB,GAAG,IAAI,KACtC,QAAQ,mBAAmB,CAS7B,CAAC"}
|
package/out/i18n/index.js
CHANGED
|
@@ -36,6 +36,13 @@ const getTranslations = async (locale = null, options = {
|
|
|
36
36
|
return await translationsGetter.getTranslations(targetLocale, options);
|
|
37
37
|
};
|
|
38
38
|
exports.getTranslations = getTranslations;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a translation function (i.e. `t`) for the given locale.
|
|
41
|
+
* If no locale is provided, the locale from the current view context is used.
|
|
42
|
+
*
|
|
43
|
+
* @param locale The locale to create the translation function for.
|
|
44
|
+
* @returns The translation function.
|
|
45
|
+
*/
|
|
39
46
|
const createTranslationFunction = async (locale = null) => {
|
|
40
47
|
let targetLocale = locale;
|
|
41
48
|
if (!targetLocale) {
|
package/out/invoke/invoke.d.ts
CHANGED
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
import type { Definitions, DefArguments, DefResult } from '@forge/resolver/shared';
|
|
2
|
-
import { InvokePayload } from '../types';
|
|
3
|
-
|
|
2
|
+
import { InvokePayload, InvokeResponse } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Calls a resolver function with explicit payload and return types.
|
|
5
|
+
*
|
|
6
|
+
* The first generic is the payload shape and the second generic is the return type.
|
|
7
|
+
* When this overload is used, payload is required.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* type Payload = { name: string };
|
|
11
|
+
* type Response = { message: string };
|
|
12
|
+
* const response = await invoke<Payload, Response>('greet', { name: 'Taylor' });
|
|
13
|
+
*/
|
|
14
|
+
export declare function invoke<Payload extends InvokePayload, T = InvokeResponse>(functionKey: string, payload: Payload): Promise<T>;
|
|
15
|
+
/**
|
|
16
|
+
* Calls a resolver function using the legacy generic form where the type argument is the return type.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const response = await invoke<{ message: string }>('greet', { name: 'Taylor' });
|
|
20
|
+
*/
|
|
21
|
+
export declare function invoke<T = InvokeResponse>(functionKey: string, payload?: InvokePayload): Promise<T>;
|
|
4
22
|
declare type Invoke<Defs extends Definitions> = <Def extends keyof Defs & string>(call: Def, ...arg: DefArguments<Defs, Def>) => Promise<DefResult<Defs, Def>>;
|
|
23
|
+
/**
|
|
24
|
+
* Specialises the invoke function to a given Definitions type.
|
|
25
|
+
*
|
|
26
|
+
* @returns An invoke function that can be used to call backend functions.
|
|
27
|
+
*/
|
|
5
28
|
export declare function makeInvoke<Defs extends Definitions>(): Invoke<Defs>;
|
|
6
29
|
export {};
|
|
7
30
|
//# sourceMappingURL=invoke.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/invoke/invoke.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInF,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/invoke/invoke.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA+BzD;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,OAAO,SAAS,aAAa,EAAE,CAAC,GAAG,cAAc,EACtE,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,CAAC,CAAC,CAAC;AAEd;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,cAAc,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AASrG,aAAK,MAAM,CAAC,IAAI,SAAS,WAAW,IAAI,CAAC,GAAG,SAAS,MAAM,IAAI,GAAG,MAAM,EACtE,IAAI,EAAE,GAAG,EACT,GAAG,GAAG,EAAE,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,KAC5B,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAEnC;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,SAAS,WAAW,KAAK,MAAM,CAAC,IAAI,CAAC,CAEnE"}
|
package/out/invoke/invoke.js
CHANGED
|
@@ -19,8 +19,20 @@ const _invoke = (functionKey, payload) => {
|
|
|
19
19
|
validatePayload(payload);
|
|
20
20
|
return callBridge('invoke', { functionKey, payload });
|
|
21
21
|
};
|
|
22
|
-
|
|
22
|
+
const limitedInvoke = (0, utils_1.withRateLimiter)(_invoke, 500, 1000 * 25, 'Resolver calls are rate limited at 500req/25s');
|
|
23
|
+
/**
|
|
24
|
+
* Calls a backend resolver function by key.
|
|
25
|
+
*/
|
|
26
|
+
function invoke(functionKey, payload) {
|
|
27
|
+
return limitedInvoke(functionKey, payload);
|
|
28
|
+
}
|
|
29
|
+
exports.invoke = invoke;
|
|
30
|
+
/**
|
|
31
|
+
* Specialises the invoke function to a given Definitions type.
|
|
32
|
+
*
|
|
33
|
+
* @returns An invoke function that can be used to call backend functions.
|
|
34
|
+
*/
|
|
23
35
|
function makeInvoke() {
|
|
24
|
-
return
|
|
36
|
+
return invoke;
|
|
25
37
|
}
|
|
26
38
|
exports.makeInvoke = makeInvoke;
|
package/out/modal/modal.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Modal = void 0;
|
|
|
4
4
|
const bridge_1 = require("../bridge");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
6
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
7
8
|
const noop = () => { };
|
|
8
9
|
class Modal {
|
|
9
10
|
constructor(opts) {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delete multiple objects
|
|
3
|
+
*
|
|
4
|
+
* @param functionKey - Configuration object containing the backend function key to delete objects
|
|
5
|
+
* @param keys - Array of object keys to delete
|
|
6
|
+
* @returns Promise<void>
|
|
7
|
+
* @throws {BridgeAPIError} When deleting fails
|
|
8
|
+
*/
|
|
1
9
|
export declare const deleteObjects: ({ functionKey, keys }: {
|
|
2
10
|
functionKey: string;
|
|
3
11
|
keys: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteObjects.d.ts","sourceRoot":"","sources":["../../src/object-store/deleteObjects.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deleteObjects.d.ts","sourceRoot":"","sources":["../../src/object-store/deleteObjects.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;iBAAgD,MAAM;UAAQ,MAAM,EAAE;MAAK,QAAQ,IAAI,CAkBhH,CAAC"}
|
|
@@ -6,6 +6,14 @@ const errors_1 = require("../errors");
|
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const bridge_1 = require("../bridge");
|
|
8
8
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
9
|
+
/**
|
|
10
|
+
* Delete multiple objects
|
|
11
|
+
*
|
|
12
|
+
* @param functionKey - Configuration object containing the backend function key to delete objects
|
|
13
|
+
* @param keys - Array of object keys to delete
|
|
14
|
+
* @returns Promise<void>
|
|
15
|
+
* @throws {BridgeAPIError} When deleting fails
|
|
16
|
+
*/
|
|
9
17
|
const deleteObjects = async ({ functionKey, keys }) => {
|
|
10
18
|
await (0, utils_1.checkRestrictedEnvironment)();
|
|
11
19
|
void callBridge('trackObjectStoreAction', { action: 'delete' });
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { DownloadResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Download multiple objects from pre-signed URLs
|
|
4
|
+
*
|
|
5
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate download URLs
|
|
6
|
+
* @param keys - Array of object keys to download
|
|
7
|
+
* @returns Promise resolving to DownloadResult[]
|
|
8
|
+
* @throws {BridgeAPIError} When filtering fails or download encounters an error
|
|
9
|
+
*/
|
|
2
10
|
export declare const download: ({ functionKey, keys }: {
|
|
3
11
|
functionKey: string;
|
|
4
12
|
keys: string[];
|
|
@@ -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;
|
|
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;AAMlE;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ;iBAIN,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,cAAc,EAAE,CAyD3B,CAAC"}
|
|
@@ -6,6 +6,14 @@ const errors_1 = require("../errors");
|
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const bridge_1 = require("../bridge");
|
|
8
8
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
9
|
+
/**
|
|
10
|
+
* Download multiple objects from pre-signed URLs
|
|
11
|
+
*
|
|
12
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate download URLs
|
|
13
|
+
* @param keys - Array of object keys to download
|
|
14
|
+
* @returns Promise resolving to DownloadResult[]
|
|
15
|
+
* @throws {BridgeAPIError} When filtering fails or download encounters an error
|
|
16
|
+
*/
|
|
9
17
|
const download = async ({ functionKey, keys }) => {
|
|
10
18
|
await (0, utils_1.checkRestrictedEnvironment)();
|
|
11
19
|
void callBridge('trackObjectStoreAction', { action: 'download' });
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { GetMetadataResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Get metadata for multiple objectIds
|
|
4
|
+
*
|
|
5
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate object metadata
|
|
6
|
+
* @param keys - Array of object keys to get metadata for
|
|
7
|
+
* @returns Promise resolving to GetMetadataResult[]
|
|
8
|
+
* @throws {BridgeAPIError} When filtering fails or download encounters an error
|
|
9
|
+
*/
|
|
2
10
|
export declare const getMetadata: ({ functionKey, keys }: {
|
|
3
11
|
functionKey: string;
|
|
4
12
|
keys: string[];
|
|
@@ -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;
|
|
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;AAMjD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW;iBAIT,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,iBAAiB,EAAE,CA6B9B,CAAC"}
|
|
@@ -6,6 +6,14 @@ const errors_1 = require("../errors");
|
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const bridge_1 = require("../bridge");
|
|
8
8
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
9
|
+
/**
|
|
10
|
+
* Get metadata for multiple objectIds
|
|
11
|
+
*
|
|
12
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate object metadata
|
|
13
|
+
* @param keys - Array of object keys to get metadata for
|
|
14
|
+
* @returns Promise resolving to GetMetadataResult[]
|
|
15
|
+
* @throws {BridgeAPIError} When filtering fails or download encounters an error
|
|
16
|
+
*/
|
|
9
17
|
const getMetadata = async ({ functionKey, keys }) => {
|
|
10
18
|
await (0, utils_1.checkRestrictedEnvironment)();
|
|
11
19
|
void callBridge('trackObjectStoreAction', { action: 'getMetadata' });
|
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
import type { UploadResult, UploadObject, UploadPromiseItem } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Start individual upload operations and return array of promises
|
|
4
|
+
* This allows tracking per-file upload progress
|
|
5
|
+
*
|
|
6
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate presigned URLs
|
|
7
|
+
* @param objects - Array of Blob objects or Base64Object (with data and optional mimeType) to upload
|
|
8
|
+
* @returns Array of individual upload promises with their associated index
|
|
9
|
+
* @throws {BridgeAPIError} When filtering fails or upload encounters an error
|
|
10
|
+
*/
|
|
2
11
|
export declare const createUploadPromises: ({ functionKey, objects }: {
|
|
3
12
|
functionKey: string;
|
|
4
13
|
objects: UploadObject[];
|
|
5
14
|
}) => Promise<UploadPromiseItem[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Upload multiple objects to pre-signed URLs
|
|
17
|
+
*
|
|
18
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate presigned URLs
|
|
19
|
+
* @param objects - Array of Blob objects or Base64Object (with data and optional mimeType) to upload
|
|
20
|
+
* @returns Promise resolving to UploadResult[]
|
|
21
|
+
* @throws {BridgeAPIError} When filtering fails or upload encounters an error
|
|
22
|
+
*/
|
|
6
23
|
export declare const upload: ({ functionKey, objects }: {
|
|
7
24
|
functionKey: string;
|
|
8
25
|
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,iBAAiB,EAAE,MAAM,SAAS,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;AAwClH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;iBAIlB,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,iBAAiB,EAAE,CA0G9B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;iBAIJ,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,YAAY,EAAE,CASzB,CAAC"}
|
|
@@ -6,6 +6,9 @@ const errors_1 = require("../errors");
|
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const bridge_1 = require("../bridge");
|
|
8
8
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
9
|
+
/**
|
|
10
|
+
* Convert base64 string to Blob
|
|
11
|
+
*/
|
|
9
12
|
const base64ToBlob = (base64, mimeType) => {
|
|
10
13
|
const byteCharacters = atob(base64);
|
|
11
14
|
const byteNumbers = new Array(byteCharacters.length);
|
|
@@ -15,11 +18,16 @@ const base64ToBlob = (base64, mimeType) => {
|
|
|
15
18
|
const byteArray = new Uint8Array(byteNumbers);
|
|
16
19
|
return new Blob([byteArray], { type: mimeType || 'application/octet-stream' });
|
|
17
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Get metadata for a blob object including size and checksum
|
|
23
|
+
*/
|
|
18
24
|
const getObjectMetadata = async (blob) => {
|
|
19
25
|
const length = blob.size;
|
|
26
|
+
// Calculate checksum using SubtleCrypto API
|
|
20
27
|
const arrayBuffer = await blob.arrayBuffer();
|
|
21
28
|
const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
|
|
22
29
|
const hashArray = new Uint8Array(hashBuffer);
|
|
30
|
+
// Convert to base64 format (required by OS API)
|
|
23
31
|
const checksum = btoa(String.fromCharCode(...hashArray));
|
|
24
32
|
const checksumType = 'SHA256';
|
|
25
33
|
return {
|
|
@@ -28,6 +36,15 @@ const getObjectMetadata = async (blob) => {
|
|
|
28
36
|
checksumType
|
|
29
37
|
};
|
|
30
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Start individual upload operations and return array of promises
|
|
41
|
+
* This allows tracking per-file upload progress
|
|
42
|
+
*
|
|
43
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate presigned URLs
|
|
44
|
+
* @param objects - Array of Blob objects or Base64Object (with data and optional mimeType) to upload
|
|
45
|
+
* @returns Array of individual upload promises with their associated index
|
|
46
|
+
* @throws {BridgeAPIError} When filtering fails or upload encounters an error
|
|
47
|
+
*/
|
|
31
48
|
const createUploadPromises = async ({ functionKey, objects }) => {
|
|
32
49
|
if (!functionKey || functionKey.length === 0) {
|
|
33
50
|
throw new errors_1.BridgeAPIError('functionKey is required to filter and generate presigned URLs');
|
|
@@ -35,6 +52,7 @@ const createUploadPromises = async ({ functionKey, objects }) => {
|
|
|
35
52
|
if (!Array.isArray(objects) || objects.length === 0) {
|
|
36
53
|
throw new errors_1.BridgeAPIError('objects array is required and must not be empty');
|
|
37
54
|
}
|
|
55
|
+
// Validate and convert objects to Blobs in a single pass
|
|
38
56
|
const blobs = objects.map((obj, index) => {
|
|
39
57
|
if (obj instanceof Blob) {
|
|
40
58
|
return obj;
|
|
@@ -119,6 +137,14 @@ const createUploadPromises = async ({ functionKey, objects }) => {
|
|
|
119
137
|
return uploadPromises;
|
|
120
138
|
};
|
|
121
139
|
exports.createUploadPromises = createUploadPromises;
|
|
140
|
+
/**
|
|
141
|
+
* Upload multiple objects to pre-signed URLs
|
|
142
|
+
*
|
|
143
|
+
* @param functionKey - Configuration object containing the backend function key to filter and generate presigned URLs
|
|
144
|
+
* @param objects - Array of Blob objects or Base64Object (with data and optional mimeType) to upload
|
|
145
|
+
* @returns Promise resolving to UploadResult[]
|
|
146
|
+
* @throws {BridgeAPIError} When filtering fails or upload encounters an error
|
|
147
|
+
*/
|
|
122
148
|
const upload = async ({ functionKey, objects }) => {
|
|
123
149
|
await (0, utils_1.checkRestrictedEnvironment)();
|
|
124
150
|
void callBridge('trackObjectStoreAction', { action: 'upload' });
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import type { External } from '@forge/manifest';
|
|
2
2
|
import type { RuntimePermissions } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Resource types that can be loaded externally
|
|
5
|
+
*/
|
|
3
6
|
declare const RESOURCE_TYPES: readonly ["fonts", "styles", "frames", "images", "media", "scripts"];
|
|
4
7
|
export declare type ResourceType = (typeof RESOURCE_TYPES)[number];
|
|
8
|
+
/**
|
|
9
|
+
* Fetch types for external requests
|
|
10
|
+
*/
|
|
5
11
|
declare const FETCH_TYPES: readonly ["backend", "client"];
|
|
6
12
|
export declare type FetchType = (typeof FETCH_TYPES)[number];
|
|
13
|
+
/**
|
|
14
|
+
* Required permissions for checking
|
|
15
|
+
*/
|
|
7
16
|
export interface PermissionRequirements {
|
|
8
17
|
scopes?: string[];
|
|
9
18
|
external?: {
|
|
@@ -20,20 +29,62 @@ export interface PermissionRequirements {
|
|
|
20
29
|
};
|
|
21
30
|
content?: Record<string, unknown>;
|
|
22
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Missing permissions information
|
|
34
|
+
*/
|
|
23
35
|
export declare type MissingPermissions = PermissionRequirements;
|
|
36
|
+
/**
|
|
37
|
+
* Permission check result
|
|
38
|
+
*/
|
|
24
39
|
export interface PermissionCheckResult {
|
|
25
40
|
granted: boolean;
|
|
26
41
|
missing: MissingPermissions | null;
|
|
27
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Permission utilities for checking runtime permissions
|
|
45
|
+
*/
|
|
28
46
|
export interface PermissionUtils {
|
|
47
|
+
/**
|
|
48
|
+
* Check if a specific scope is granted
|
|
49
|
+
*/
|
|
29
50
|
hasScope: (scope: string) => boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Check if fetching from a URL is allowed for the given fetch type
|
|
53
|
+
* @param type - 'backend' (hostname-only matching) or 'client' (CSP validation with paths)
|
|
54
|
+
* @param url - The URL to check
|
|
55
|
+
*/
|
|
30
56
|
canFetchFrom: (type: FetchType, url: string) => boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Check if loading a resource from a URL is allowed
|
|
59
|
+
* @param type - The resource type (fonts, styles, frames, images, media, scripts)
|
|
60
|
+
* @param url - The URL to check
|
|
61
|
+
*/
|
|
31
62
|
canLoadResource: (type: ResourceType, url: string) => boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Get all granted scopes
|
|
65
|
+
*/
|
|
32
66
|
getScopes: () => string[];
|
|
67
|
+
/**
|
|
68
|
+
* Get all external permissions
|
|
69
|
+
*/
|
|
33
70
|
getExternalPermissions: () => External | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Check if any permissions are granted
|
|
73
|
+
*/
|
|
34
74
|
hasAnyPermissions: () => boolean;
|
|
35
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Create permission utilities from runtime permissions
|
|
78
|
+
* @param runtimePermissions - The runtime permissions from context
|
|
79
|
+
* @returns Permission utilities or null if permissions are not available
|
|
80
|
+
*/
|
|
36
81
|
export declare function createPermissionUtils(runtimePermissions: RuntimePermissions | undefined): PermissionUtils | null;
|
|
82
|
+
/**
|
|
83
|
+
* Check if required permissions are granted
|
|
84
|
+
* @param requiredPermissions - The permissions required to check
|
|
85
|
+
* @param runtimePermissions - The runtime permissions from context (optional, will be fetched from view.getContext() if not provided)
|
|
86
|
+
* @returns Promise resolving to permission check result with granted status and missing permissions
|
|
87
|
+
*/
|
|
37
88
|
export declare function checkPermissions(requiredPermissions: PermissionRequirements, runtimePermissions?: RuntimePermissions | undefined): Promise<PermissionCheckResult>;
|
|
38
89
|
export {};
|
|
39
90
|
//# sourceMappingURL=permissionsUtil.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionsUtil.d.ts","sourceRoot":"","sources":["../../src/permissions/permissionsUtil.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAS,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"permissionsUtil.d.ts","sourceRoot":"","sources":["../../src/permissions/permissionsUtil.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAS,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAiBnD;;GAEG;AACH,QAAA,MAAM,cAAc,sEAAuE,CAAC;AAC5F,oBAAY,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;GAEG;AACH,QAAA,MAAM,WAAW,gCAAiC,CAAC;AACnD,oBAAY,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE;YACN,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;YACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;SACnB,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,oBAAY,kBAAkB,GAAG,sBAAsB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAErC;;;;OAIG;IACH,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAExD;;;;OAIG;IACH,eAAe,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAE9D;;OAEG;IACH,SAAS,EAAE,MAAM,MAAM,EAAE,CAAC;IAE1B;;OAEG;IACH,sBAAsB,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAC;IAEnD;;OAEG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAmDhH;AAyID;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,mBAAmB,EAAE,sBAAsB,EAC3C,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,SAAS,GAClD,OAAO,CAAC,qBAAqB,CAAC,CAiDhC"}
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.checkPermissions = exports.createPermissionUtils = void 0;
|
|
4
4
|
const egress_1 = require("@forge/egress");
|
|
5
5
|
const view_1 = require("../view");
|
|
6
|
+
/**
|
|
7
|
+
* Helper function to extract URL string from external URL permissions.
|
|
8
|
+
* Matches the implementation in @forge/api for consistency.
|
|
9
|
+
*/
|
|
6
10
|
function extractUrlString(url) {
|
|
7
11
|
if (typeof url === 'string') {
|
|
8
12
|
return url;
|
|
@@ -12,8 +16,19 @@ function extractUrlString(url) {
|
|
|
12
16
|
}
|
|
13
17
|
return url.remote || '';
|
|
14
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Resource types that can be loaded externally
|
|
21
|
+
*/
|
|
15
22
|
const RESOURCE_TYPES = ['fonts', 'styles', 'frames', 'images', 'media', 'scripts'];
|
|
23
|
+
/**
|
|
24
|
+
* Fetch types for external requests
|
|
25
|
+
*/
|
|
16
26
|
const FETCH_TYPES = ['backend', 'client'];
|
|
27
|
+
/**
|
|
28
|
+
* Create permission utilities from runtime permissions
|
|
29
|
+
* @param runtimePermissions - The runtime permissions from context
|
|
30
|
+
* @returns Permission utilities or null if permissions are not available
|
|
31
|
+
*/
|
|
17
32
|
function createPermissionUtils(runtimePermissions) {
|
|
18
33
|
if (!runtimePermissions) {
|
|
19
34
|
return null;
|
|
@@ -27,10 +42,13 @@ function createPermissionUtils(runtimePermissions) {
|
|
|
27
42
|
const fetchUrls = (_a = external.fetch) === null || _a === void 0 ? void 0 : _a[type];
|
|
28
43
|
if (!(fetchUrls === null || fetchUrls === void 0 ? void 0 : fetchUrls.length))
|
|
29
44
|
return false;
|
|
45
|
+
// Extract URLs and create egress filter
|
|
30
46
|
const allowList = fetchUrls.map(extractUrlString).filter((u) => u.length > 0);
|
|
31
47
|
if (allowList.length === 0)
|
|
32
48
|
return false;
|
|
33
49
|
const egressFilter = new egress_1.EgressFilteringService(allowList);
|
|
50
|
+
// Backend: hostname-only matching, Client: CSP validation (includes paths)
|
|
51
|
+
// Type assertion needed because node_modules may have outdated types
|
|
34
52
|
const egressFilterWithCSP = egressFilter;
|
|
35
53
|
return type === 'client' ? egressFilterWithCSP.isValidUrlCSP(url) : egressFilter.isValidUrl(url);
|
|
36
54
|
},
|
|
@@ -38,10 +56,13 @@ function createPermissionUtils(runtimePermissions) {
|
|
|
38
56
|
const resourceUrls = external[type];
|
|
39
57
|
if (!(resourceUrls === null || resourceUrls === void 0 ? void 0 : resourceUrls.length))
|
|
40
58
|
return false;
|
|
59
|
+
// Extract URLs and create egress filter
|
|
41
60
|
const allowList = resourceUrls.map(extractUrlString).filter((u) => u.length > 0);
|
|
42
61
|
if (allowList.length === 0)
|
|
43
62
|
return false;
|
|
44
63
|
const egressFilter = new egress_1.EgressFilteringService(allowList);
|
|
64
|
+
// All resources use CSP validation (checks protocol + hostname + paths)
|
|
65
|
+
// Type assertion needed because node_modules may have outdated types
|
|
45
66
|
const egressFilterWithCSP = egressFilter;
|
|
46
67
|
return egressFilterWithCSP.isValidUrlCSP(url);
|
|
47
68
|
},
|
|
@@ -51,6 +72,9 @@ function createPermissionUtils(runtimePermissions) {
|
|
|
51
72
|
};
|
|
52
73
|
}
|
|
53
74
|
exports.createPermissionUtils = createPermissionUtils;
|
|
75
|
+
/**
|
|
76
|
+
* Check if required scopes are granted
|
|
77
|
+
*/
|
|
54
78
|
function checkScopes(requiredScopes, permissionUtils) {
|
|
55
79
|
if (!(requiredScopes === null || requiredScopes === void 0 ? void 0 : requiredScopes.length)) {
|
|
56
80
|
return undefined;
|
|
@@ -58,6 +82,9 @@ function checkScopes(requiredScopes, permissionUtils) {
|
|
|
58
82
|
const missingScopes = requiredScopes.filter((scope) => !permissionUtils.hasScope(scope));
|
|
59
83
|
return missingScopes.length > 0 ? missingScopes : undefined;
|
|
60
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Check if required fetch permissions are granted
|
|
87
|
+
*/
|
|
61
88
|
function checkFetchPermissions(requiredFetch, permissionUtils) {
|
|
62
89
|
if (!(requiredFetch === null || requiredFetch === void 0 ? void 0 : requiredFetch.fetch)) {
|
|
63
90
|
return undefined;
|
|
@@ -75,6 +102,9 @@ function checkFetchPermissions(requiredFetch, permissionUtils) {
|
|
|
75
102
|
});
|
|
76
103
|
return Object.keys(missingFetch).length > 0 ? missingFetch : undefined;
|
|
77
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if required resource permissions are granted
|
|
107
|
+
*/
|
|
78
108
|
function checkResourcePermissions(requiredExternal, permissionUtils) {
|
|
79
109
|
const missingResources = {};
|
|
80
110
|
RESOURCE_TYPES.forEach((type) => {
|
|
@@ -88,6 +118,9 @@ function checkResourcePermissions(requiredExternal, permissionUtils) {
|
|
|
88
118
|
});
|
|
89
119
|
return Object.keys(missingResources).length > 0 ? missingResources : undefined;
|
|
90
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Check if required external permissions are granted
|
|
123
|
+
*/
|
|
91
124
|
function checkExternalPermissions(requiredExternal, permissionUtils) {
|
|
92
125
|
if (!requiredExternal) {
|
|
93
126
|
return undefined;
|
|
@@ -106,6 +139,8 @@ function checkExternalPermissions(requiredExternal, permissionUtils) {
|
|
|
106
139
|
}
|
|
107
140
|
return missingExternal;
|
|
108
141
|
}
|
|
142
|
+
// Throws if a field that should be a plain object but is something else.
|
|
143
|
+
// Only used for external and external.fetch, which are guarded above.
|
|
109
144
|
function validateObjectField(value, fieldPath) {
|
|
110
145
|
if (value !== undefined) {
|
|
111
146
|
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
@@ -113,11 +148,15 @@ function validateObjectField(value, fieldPath) {
|
|
|
113
148
|
}
|
|
114
149
|
}
|
|
115
150
|
}
|
|
151
|
+
// Throws if a field that should be an array but is something else.
|
|
116
152
|
function validateArrayField(value, fieldPath) {
|
|
117
153
|
if (value !== undefined && !Array.isArray(value)) {
|
|
118
154
|
throw new TypeError(`${fieldPath} should be an array, not a ${typeof value}`);
|
|
119
155
|
}
|
|
120
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Validates that fields in requiredPermissions have the correct types.
|
|
159
|
+
*/
|
|
121
160
|
function validatePermissionShape(requiredPermissions) {
|
|
122
161
|
validateArrayField(requiredPermissions.scopes, 'scopes');
|
|
123
162
|
const external = requiredPermissions.external;
|
|
@@ -134,15 +173,24 @@ function validatePermissionShape(requiredPermissions) {
|
|
|
134
173
|
validateArrayField(external[type], `external.${type}`);
|
|
135
174
|
}
|
|
136
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if required permissions are granted
|
|
178
|
+
* @param requiredPermissions - The permissions required to check
|
|
179
|
+
* @param runtimePermissions - The runtime permissions from context (optional, will be fetched from view.getContext() if not provided)
|
|
180
|
+
* @returns Promise resolving to permission check result with granted status and missing permissions
|
|
181
|
+
*/
|
|
137
182
|
async function checkPermissions(requiredPermissions, runtimePermissions) {
|
|
138
183
|
var _a;
|
|
184
|
+
// Early return for falsy required permissions
|
|
139
185
|
if (!requiredPermissions) {
|
|
140
186
|
return { granted: false, missing: null };
|
|
141
187
|
}
|
|
142
188
|
validatePermissionShape(requiredPermissions);
|
|
189
|
+
// Early return for empty permissions (no requirements = all granted)
|
|
143
190
|
if (!((_a = requiredPermissions.scopes) === null || _a === void 0 ? void 0 : _a.length) && !requiredPermissions.external) {
|
|
144
191
|
return { granted: true, missing: null };
|
|
145
192
|
}
|
|
193
|
+
// If runtimePermissions is not provided, fetch it from context
|
|
146
194
|
let permissionsToCheck = runtimePermissions;
|
|
147
195
|
if (!permissionsToCheck) {
|
|
148
196
|
const context = await view_1.view.getContext();
|
|
@@ -150,20 +198,24 @@ async function checkPermissions(requiredPermissions, runtimePermissions) {
|
|
|
150
198
|
}
|
|
151
199
|
const permissionUtils = createPermissionUtils(permissionsToCheck);
|
|
152
200
|
if (!permissionUtils) {
|
|
201
|
+
// If permissions are not available, return not granted
|
|
153
202
|
return { granted: false, missing: null };
|
|
154
203
|
}
|
|
155
204
|
const missing = {};
|
|
156
205
|
let hasAllRequiredPermissions = true;
|
|
206
|
+
// Check scopes
|
|
157
207
|
const missingScopes = checkScopes(requiredPermissions.scopes, permissionUtils);
|
|
158
208
|
if (missingScopes) {
|
|
159
209
|
missing.scopes = missingScopes;
|
|
160
210
|
hasAllRequiredPermissions = false;
|
|
161
211
|
}
|
|
212
|
+
// Check external permissions
|
|
162
213
|
const missingExternal = checkExternalPermissions(requiredPermissions.external, permissionUtils);
|
|
163
214
|
if (missingExternal) {
|
|
164
215
|
missing.external = missingExternal;
|
|
165
216
|
hasAllRequiredPermissions = false;
|
|
166
217
|
}
|
|
218
|
+
// Note: Content permissions are not supported in the current RuntimePermissions type
|
|
167
219
|
return {
|
|
168
220
|
granted: hasAllRequiredPermissions,
|
|
169
221
|
missing: hasAllRequiredPermissions ? null : missing
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// These enum values directly map to properties in the context.extension object in a product's FCT.
|
|
3
|
+
// It allows a subset of properties to be specified for Realtime channel authorization.
|
|
2
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
5
|
exports.Bitbucket = exports.Confluence = exports.Jira = void 0;
|
|
4
6
|
var Jira;
|
package/out/router/router.js
CHANGED
|
@@ -3,6 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.router = void 0;
|
|
4
4
|
const bridge_1 = require("../bridge");
|
|
5
5
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
6
|
+
/**
|
|
7
|
+
* Returns a URL object for a given location.
|
|
8
|
+
*
|
|
9
|
+
* @param location - The location to get the URL for
|
|
10
|
+
* @returns A URL object for the given location
|
|
11
|
+
*/
|
|
6
12
|
const getUrl = async (location) => {
|
|
7
13
|
if (!(location === null || location === void 0 ? void 0 : location.target)) {
|
|
8
14
|
throw new Error('target is required for getUrl');
|
|
@@ -18,6 +24,12 @@ const getUrl = async (location) => {
|
|
|
18
24
|
throw new Error(`Failed to parse URL: ${url} (${error})`);
|
|
19
25
|
}
|
|
20
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Navigates to a location within the same tab.
|
|
29
|
+
*
|
|
30
|
+
* @param location URL or `NavigationLocation` object
|
|
31
|
+
* @returns a promise that resolves when navigation is complete
|
|
32
|
+
*/
|
|
21
33
|
const navigate = (location) => {
|
|
22
34
|
if (typeof location === 'string') {
|
|
23
35
|
return callBridge('navigate', { url: location, type: 'same-tab' });
|
|
@@ -29,6 +41,12 @@ const navigate = (location) => {
|
|
|
29
41
|
return callBridge('navigate', { ...location, type: 'same-tab' });
|
|
30
42
|
}
|
|
31
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* Opens a new tab in the browser and navigates to the specified location.
|
|
46
|
+
*
|
|
47
|
+
* @param location URL or `NavigationLocation` object
|
|
48
|
+
* @returns a promise that resolves when navigation is complete
|
|
49
|
+
*/
|
|
32
50
|
const open = (location) => {
|
|
33
51
|
if (typeof location === 'string') {
|
|
34
52
|
return callBridge('navigate', { url: location, type: 'new-tab' });
|
|
@@ -40,6 +58,11 @@ const open = (location) => {
|
|
|
40
58
|
return callBridge('navigate', { ...location, type: 'new-tab' });
|
|
41
59
|
}
|
|
42
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* Reloads the page.
|
|
63
|
+
*
|
|
64
|
+
* @returns a promise that resolves to void when the page is reloaded
|
|
65
|
+
*/
|
|
43
66
|
const reload = async () => callBridge('reload');
|
|
44
67
|
exports.router = {
|
|
45
68
|
getUrl,
|
package/out/router/targets.d.ts
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
export declare const NavigationTarget: {
|
|
2
|
+
/**
|
|
3
|
+
* The view page for pages, blogs and custom content. Takes a contentId to identify the content.
|
|
4
|
+
*/
|
|
2
5
|
readonly ContentView: "contentView";
|
|
6
|
+
/**
|
|
7
|
+
* The edit page for pages, blogs and custom content. Takes a contentId to identify the content.
|
|
8
|
+
*/
|
|
3
9
|
readonly ContentEdit: "contentEdit";
|
|
10
|
+
/**
|
|
11
|
+
* The list/collector page for pages, blogs and custom content contained in a space. Takes a spaceKey and a contentType to identify the content type for pages and blogs. Takes a moduleKey for custom content.
|
|
12
|
+
*/
|
|
4
13
|
readonly ContentList: "contentList";
|
|
14
|
+
/**
|
|
15
|
+
* The space view page. Takes a spaceKey to identify the space.
|
|
16
|
+
*/
|
|
5
17
|
readonly SpaceView: "spaceView";
|
|
18
|
+
/**
|
|
19
|
+
* The page within a specific module. Takes a moduleKey to identify the correct module.
|
|
20
|
+
*/
|
|
6
21
|
readonly Module: "module";
|
|
22
|
+
/**
|
|
23
|
+
* The profile page for a specific user. Takes an accountId to identify the user.
|
|
24
|
+
*/
|
|
7
25
|
readonly UserProfile: "userProfile";
|
|
26
|
+
/**
|
|
27
|
+
* A dashboard in Jira. Takes a dashboardId to identify the dashboard.
|
|
28
|
+
*/
|
|
8
29
|
readonly Dashboard: "dashboard";
|
|
30
|
+
/**
|
|
31
|
+
* An issue in Jira. Takes an issueKey to identify the issue.
|
|
32
|
+
*/
|
|
9
33
|
readonly Issue: "issue";
|
|
34
|
+
/**
|
|
35
|
+
* The project settings details of a Jira project. Takes a projectKey to identify the project. Only accessible to administrators.
|
|
36
|
+
*/
|
|
10
37
|
readonly ProjectSettingsDetails: "projectSettingsDetails";
|
|
11
38
|
};
|
|
12
39
|
//# sourceMappingURL=targets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../src/router/targets.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../src/router/targets.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;CAEK,CAAC"}
|
package/out/router/targets.js
CHANGED
|
@@ -1,14 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NavigationTarget = void 0;
|
|
4
|
+
// Constants for developer convenience. The JS Docs below will also be displayed in the IDE when the developer is using this object.
|
|
4
5
|
exports.NavigationTarget = {
|
|
6
|
+
/**
|
|
7
|
+
* The view page for pages, blogs and custom content. Takes a contentId to identify the content.
|
|
8
|
+
*/
|
|
5
9
|
ContentView: 'contentView',
|
|
10
|
+
/**
|
|
11
|
+
* The edit page for pages, blogs and custom content. Takes a contentId to identify the content.
|
|
12
|
+
*/
|
|
6
13
|
ContentEdit: 'contentEdit',
|
|
14
|
+
/**
|
|
15
|
+
* The list/collector page for pages, blogs and custom content contained in a space. Takes a spaceKey and a contentType to identify the content type for pages and blogs. Takes a moduleKey for custom content.
|
|
16
|
+
*/
|
|
7
17
|
ContentList: 'contentList',
|
|
18
|
+
/**
|
|
19
|
+
* The space view page. Takes a spaceKey to identify the space.
|
|
20
|
+
*/
|
|
8
21
|
SpaceView: 'spaceView',
|
|
22
|
+
/**
|
|
23
|
+
* The page within a specific module. Takes a moduleKey to identify the correct module.
|
|
24
|
+
*/
|
|
9
25
|
Module: 'module',
|
|
26
|
+
/**
|
|
27
|
+
* The profile page for a specific user. Takes an accountId to identify the user.
|
|
28
|
+
*/
|
|
10
29
|
UserProfile: 'userProfile',
|
|
30
|
+
/**
|
|
31
|
+
* A dashboard in Jira. Takes a dashboardId to identify the dashboard.
|
|
32
|
+
*/
|
|
11
33
|
Dashboard: 'dashboard',
|
|
34
|
+
/**
|
|
35
|
+
* An issue in Jira. Takes an issueKey to identify the issue.
|
|
36
|
+
*/
|
|
12
37
|
Issue: 'issue',
|
|
38
|
+
/**
|
|
39
|
+
* The project settings details of a Jira project. Takes a projectKey to identify the project. Only accessible to administrators.
|
|
40
|
+
*/
|
|
13
41
|
ProjectSettingsDetails: 'projectSettingsDetails'
|
|
14
42
|
};
|
package/out/rovo/isEnabled.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isEnabled.d.ts","sourceRoot":"","sources":["../../src/rovo/isEnabled.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"isEnabled.d.ts","sourceRoot":"","sources":["../../src/rovo/isEnabled.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,SAAS,wBAErB,CAAC"}
|
package/out/rovo/isEnabled.js
CHANGED
|
@@ -3,6 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.isEnabled = void 0;
|
|
4
4
|
const bridge_1 = require("../bridge");
|
|
5
5
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
6
|
+
/**
|
|
7
|
+
* Checks if Rovo is enabled for the current tenant.
|
|
8
|
+
*
|
|
9
|
+
* @returns boolean
|
|
10
|
+
*/
|
|
6
11
|
const isEnabled = () => {
|
|
7
12
|
return callBridge('isRovoEnabled');
|
|
8
13
|
};
|
package/out/rovo/open.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { OpenRovoPayload } from './types';
|
|
2
2
|
export declare const OPEN_ROVO_BRIDGE_ERROR_MESSAGE = "Unable to open Rovo Chat due to usage in an unsupported product. Only Confluence, Jira and some Jira Service Management modules are supported at this point. See https://developer.atlassian.com/platform/forge/apis-reference/ui-api-bridge/rovo/";
|
|
3
|
+
/**
|
|
4
|
+
* Opens Rovo chat from the given Rovo agent name.
|
|
5
|
+
*
|
|
6
|
+
* @param {OpenRovoPayload} [openRovoPayload] - Payload to open chat.
|
|
7
|
+
* Can be one of:
|
|
8
|
+
* - ForgeAgentPayload: { agentName: string, agentKey: string, prompt?: string }
|
|
9
|
+
* - AtlassianAgentPayload: { agentName: string, prompt?: string }
|
|
10
|
+
* - DefaultAgentPayload: { prompt?: string }
|
|
11
|
+
*/
|
|
3
12
|
export declare const open: (openRovoPayload: OpenRovoPayload) => Promise<void>;
|
|
4
13
|
//# sourceMappingURL=open.d.ts.map
|
package/out/rovo/open.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/rovo/open.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO1C,eAAO,MAAM,8BAA8B,uPAC2M,CAAC;
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/rovo/open.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO1C,eAAO,MAAM,8BAA8B,uPAC2M,CAAC;AAmBvP;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,oBAA2B,eAAe,kBAiB1D,CAAC"}
|
package/out/rovo/open.js
CHANGED
|
@@ -23,6 +23,15 @@ const transformRovoPayload = (openRovoPayload) => {
|
|
|
23
23
|
return { prompt: openRovoPayload.prompt };
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Opens Rovo chat from the given Rovo agent name.
|
|
28
|
+
*
|
|
29
|
+
* @param {OpenRovoPayload} [openRovoPayload] - Payload to open chat.
|
|
30
|
+
* Can be one of:
|
|
31
|
+
* - ForgeAgentPayload: { agentName: string, agentKey: string, prompt?: string }
|
|
32
|
+
* - AtlassianAgentPayload: { agentName: string, prompt?: string }
|
|
33
|
+
* - DefaultAgentPayload: { prompt?: string }
|
|
34
|
+
*/
|
|
26
35
|
const open = async (openRovoPayload) => {
|
|
27
36
|
if (openRovoPayload.type === 'forge') {
|
|
28
37
|
if (openRovoPayload.agentName.length > MAX_AGENT_LENGTH) {
|
package/out/types.d.ts
CHANGED
|
@@ -63,6 +63,12 @@ export interface LicenseDetails {
|
|
|
63
63
|
export declare type Subscription = {
|
|
64
64
|
unsubscribe: () => void;
|
|
65
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Runtime representation of app permissions that extends the manifest schema.
|
|
68
|
+
*
|
|
69
|
+
* This type represents the scopes and external permissions that the app
|
|
70
|
+
* has been granted, as configured in the manifest.yml file.
|
|
71
|
+
*/
|
|
66
72
|
export interface RuntimePermissions {
|
|
67
73
|
scopes?: Scopes;
|
|
68
74
|
external?: External;
|
package/out/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7D,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,aAAK,aAAa,GAAG;IACnB,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,oBAAY,oBAAoB,GAAG,aAAa,CAAC;AACjD,oBAAY,mBAAmB,GAAG,aAAa,CAAC;AAEhD,oBAAY,oBAAoB;IAC9B,WAAW,gBAAgB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;CAC1B;AAED,aAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,oBAAY,eAAe,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,eAAe,CAAC;IACjC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AACD,UAAU,aAAa;IACrB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,aAAK,oBAAoB;IACvB,WAAW,gBAAgB;CAC5B;AACD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC;CACtC;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,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE7D,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,aAAK,aAAa,GAAG;IACnB,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,oBAAY,oBAAoB,GAAG,aAAa,CAAC;AACjD,oBAAY,mBAAmB,GAAG,aAAa,CAAC;AAEhD,oBAAY,oBAAoB;IAC9B,WAAW,gBAAgB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;CAC1B;AAED,aAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,oBAAY,eAAe,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,eAAe,CAAC;IACjC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AACD,UAAU,aAAa;IACrB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,aAAK,oBAAoB;IACvB,WAAW,gBAAgB;CAC5B;AACD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC;CACtC;AAED,oBAAY,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAGD,oBAAY,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAE3D,oBAAY,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC"}
|
package/out/view/close.js
CHANGED
|
@@ -7,6 +7,7 @@ const callBridge = (0, bridge_1.getCallBridge)();
|
|
|
7
7
|
const close = async (payload) => {
|
|
8
8
|
try {
|
|
9
9
|
const success = await callBridge('close', payload);
|
|
10
|
+
// TODO: Modify @atlassian/forge-ui to throw if close fails instead of returning boolean DEVO-680
|
|
10
11
|
if (success === false) {
|
|
11
12
|
throw new errors_1.BridgeAPIError("this resource's view is not closable.");
|
|
12
13
|
}
|
|
@@ -7,14 +7,19 @@ const bridge_1 = require("../bridge");
|
|
|
7
7
|
const callBridge = (0, bridge_1.getCallBridge)();
|
|
8
8
|
const EXTENSION_READY = 'EXTENSION_READY';
|
|
9
9
|
const emitReadyEvent = async () => {
|
|
10
|
+
// Confluence export relies on events instead of `callBridge`
|
|
10
11
|
const context = await view_1.view.getContext();
|
|
12
|
+
// dispatches event 'forge.bridge.EXTENSION_READY' on product window
|
|
11
13
|
await events_1.events.emit(EXTENSION_READY, {
|
|
12
14
|
localId: context.localId
|
|
13
15
|
});
|
|
16
|
+
// TODO: Consider using the above event for static macros as well for to avoid two calls
|
|
17
|
+
// `callBridge` is used for static macros in XEP to signal that the forgeDoc is ready to be snapshotted
|
|
14
18
|
try {
|
|
15
19
|
await callBridge('emitReadyEvent');
|
|
16
20
|
}
|
|
17
21
|
catch {
|
|
22
|
+
// Silently ignore the error as this app may be calling this method in Confluence view mode where the method is not supported.
|
|
18
23
|
}
|
|
19
24
|
};
|
|
20
25
|
exports.emitReadyEvent = emitReadyEvent;
|
package/out/view/getContext.js
CHANGED
|
@@ -9,6 +9,8 @@ const getContext = async () => {
|
|
|
9
9
|
const context = await callBridge('getContext');
|
|
10
10
|
const locale = context === null || context === void 0 ? void 0 : context.locale;
|
|
11
11
|
if (locale) {
|
|
12
|
+
// still fallback to the locale if it is not supported,
|
|
13
|
+
// this is to avoid breaking changes
|
|
12
14
|
context.locale = (_a = (0, i18n_1.ensureLocale)(locale)) !== null && _a !== void 0 ? _a : locale;
|
|
13
15
|
}
|
|
14
16
|
return context;
|
package/out/view/open.js
CHANGED
|
@@ -7,6 +7,7 @@ const callBridge = (0, bridge_1.getCallBridge)();
|
|
|
7
7
|
const open = async () => {
|
|
8
8
|
try {
|
|
9
9
|
const success = await callBridge('open');
|
|
10
|
+
// TODO: Modify @atlassian/forge-ui to throw if close fails instead of returning boolean DEVO-680
|
|
10
11
|
if (success === false) {
|
|
11
12
|
throw new errors_1.BridgeAPIError("this resource's view is not openable.");
|
|
12
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/bridge",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.16.0-experimental-a6c6519",
|
|
4
4
|
"description": "Forge bridge API for custom UI apps",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"@atlaskit/tokens": "^1.58.0",
|
|
18
18
|
"@forge/egress": "^2.3.2",
|
|
19
19
|
"@forge/i18n": "0.0.7",
|
|
20
|
-
"@forge/resolver": "1.
|
|
20
|
+
"@forge/resolver": "1.8.0",
|
|
21
21
|
"@types/history": "^4.7.11",
|
|
22
|
-
"@forge/manifest": "12.6.0-
|
|
22
|
+
"@forge/manifest": "12.6.0-experimental-a6c6519",
|
|
23
23
|
"@types/iframe-resizer": "^3.5.8",
|
|
24
24
|
"iframe-resizer": "^4.4.5",
|
|
25
25
|
"uuid": "^9.0.1"
|