@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.
Files changed (49) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/out/events/serialiseBlob.js +11 -0
  3. package/out/featureFlags/evaluator.js +11 -2
  4. package/out/featureFlags/featureFlags.d.ts +9 -0
  5. package/out/featureFlags/featureFlags.d.ts.map +1 -1
  6. package/out/featureFlags/featureFlags.js +9 -0
  7. package/out/fetch/fetch.js +12 -0
  8. package/out/flag/flag.d.ts +7 -0
  9. package/out/flag/flag.d.ts.map +1 -1
  10. package/out/i18n/index.d.ts +15 -0
  11. package/out/i18n/index.d.ts.map +1 -1
  12. package/out/i18n/index.js +7 -0
  13. package/out/invoke/invoke.d.ts +25 -2
  14. package/out/invoke/invoke.d.ts.map +1 -1
  15. package/out/invoke/invoke.js +14 -2
  16. package/out/modal/modal.js +1 -0
  17. package/out/object-store/deleteObjects.d.ts +8 -0
  18. package/out/object-store/deleteObjects.d.ts.map +1 -1
  19. package/out/object-store/deleteObjects.js +8 -0
  20. package/out/object-store/download.d.ts +8 -0
  21. package/out/object-store/download.d.ts.map +1 -1
  22. package/out/object-store/download.js +8 -0
  23. package/out/object-store/getMetadata.d.ts +8 -0
  24. package/out/object-store/getMetadata.d.ts.map +1 -1
  25. package/out/object-store/getMetadata.js +8 -0
  26. package/out/object-store/upload.d.ts +17 -0
  27. package/out/object-store/upload.d.ts.map +1 -1
  28. package/out/object-store/upload.js +26 -0
  29. package/out/permissions/permissionsUtil.d.ts +51 -0
  30. package/out/permissions/permissionsUtil.d.ts.map +1 -1
  31. package/out/permissions/permissionsUtil.js +52 -0
  32. package/out/realtime/productContext.js +2 -0
  33. package/out/router/router.js +23 -0
  34. package/out/router/targets.d.ts +27 -0
  35. package/out/router/targets.d.ts.map +1 -1
  36. package/out/router/targets.js +28 -0
  37. package/out/rovo/isEnabled.d.ts +5 -0
  38. package/out/rovo/isEnabled.d.ts.map +1 -1
  39. package/out/rovo/isEnabled.js +5 -0
  40. package/out/rovo/open.d.ts +9 -0
  41. package/out/rovo/open.d.ts.map +1 -1
  42. package/out/rovo/open.js +9 -0
  43. package/out/types.d.ts +6 -0
  44. package/out/types.d.ts.map +1 -1
  45. package/out/view/close.js +1 -0
  46. package/out/view/emitReadyEvent.js +5 -0
  47. package/out/view/getContext.js +2 -0
  48. package/out/view/open.js +1 -0
  49. 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;IAKvC,UAAU,CACrB,IAAI,EAAE,eAAe,EACrB,MAAM,GAAE,sBAAuD,GAC9D,OAAO,CAAC,IAAI,CAAC;IAoBT,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,OAAO;IAa1D,QAAQ;IAQR,aAAa;IAIpB,OAAO,CAAC,kBAAkB;CAa3B"}
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;
@@ -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
  }
@@ -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;
@@ -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;IAKrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAIhB,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"}
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"}
@@ -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
@@ -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;AAUF,oBAAY,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AASrF,eAAO,MAAM,yBAAyB,YAC5B,wBAAwB,GAAG,IAAI,KACtC,QAAQ,mBAAmB,CAS7B,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) {
@@ -1,7 +1,30 @@
1
1
  import type { Definitions, DefArguments, DefResult } from '@forge/resolver/shared';
2
- import { InvokePayload } from '../types';
3
- export declare const invoke: <T>(functionKey: string, payload?: InvokePayload | undefined) => Promise<T>;
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,EAAkB,MAAM,UAAU,CAAC;AAuBzD,eAAO,MAAM,MAAM,6EAA4F,CAAC;AAEhH,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;AAOnC,wBAAgB,UAAU,CAAC,IAAI,SAAS,WAAW,KAAK,MAAM,CAAC,IAAI,CAAC,CAEnE"}
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"}
@@ -19,8 +19,20 @@ const _invoke = (functionKey, payload) => {
19
19
  validatePayload(payload);
20
20
  return callBridge('invoke', { functionKey, payload });
21
21
  };
22
- exports.invoke = (0, utils_1.withRateLimiter)(_invoke, 500, 1000 * 25, 'Resolver calls are rate limited at 500req/25s');
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 exports.invoke;
36
+ return invoke;
25
37
  }
26
38
  exports.makeInvoke = makeInvoke;
@@ -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":"AAeA,eAAO,MAAM,aAAa;iBAAgD,MAAM;UAAQ,MAAM,EAAE;MAAK,QAAQ,IAAI,CAkBhH,CAAC"}
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;AAclE,eAAO,MAAM,QAAQ;iBAIN,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,cAAc,EAAE,CAyD3B,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;AAcjD,eAAO,MAAM,WAAW;iBAIT,MAAM;UACb,MAAM,EAAE;MACZ,QAAQ,iBAAiB,EAAE,CA6B9B,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;AAiDlH,eAAO,MAAM,oBAAoB;iBAIlB,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,iBAAiB,EAAE,CA0G9B,CAAC;AAUF,eAAO,MAAM,MAAM;iBAIJ,MAAM;aACV,YAAY,EAAE;MACrB,QAAQ,YAAY,EAAE,CASzB,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;AAoBnD,QAAA,MAAM,cAAc,sEAAuE,CAAC;AAC5F,oBAAY,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAK3D,QAAA,MAAM,WAAW,gCAAiC,CAAC;AACnD,oBAAY,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAKrD,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;AAKD,oBAAY,kBAAkB,GAAG,sBAAsB,CAAC;AAKxD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACpC;AAKD,MAAM,WAAW,eAAe;IAI9B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAOrC,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAOxD,eAAe,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAK9D,SAAS,EAAE,MAAM,MAAM,EAAE,CAAC;IAK1B,sBAAsB,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAC;IAKnD,iBAAiB,EAAE,MAAM,OAAO,CAAC;CAClC;AAOD,wBAAgB,qBAAqB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAmDhH;AA+ID,wBAAsB,gBAAgB,CACpC,mBAAmB,EAAE,sBAAsB,EAC3C,kBAAkB,CAAC,EAAE,kBAAkB,GAAG,SAAS,GAClD,OAAO,CAAC,qBAAqB,CAAC,CAiDhC"}
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;
@@ -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,
@@ -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;;;;;;;;;;CAqCnB,CAAC"}
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"}
@@ -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
  };
@@ -1,2 +1,7 @@
1
+ /**
2
+ * Checks if Rovo is enabled for the current tenant.
3
+ *
4
+ * @returns boolean
5
+ */
1
6
  export declare const isEnabled: () => Promise<boolean>;
2
7
  //# sourceMappingURL=isEnabled.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"isEnabled.d.ts","sourceRoot":"","sources":["../../src/rovo/isEnabled.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,SAAS,wBAErB,CAAC"}
1
+ {"version":3,"file":"isEnabled.d.ts","sourceRoot":"","sources":["../../src/rovo/isEnabled.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,eAAO,MAAM,SAAS,wBAErB,CAAC"}
@@ -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
  };
@@ -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
@@ -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;AA4BvP,eAAO,MAAM,IAAI,oBAA2B,eAAe,kBAiB1D,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;
@@ -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;AAQF,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"}
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;
@@ -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.15.2-next.0",
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.7.1",
20
+ "@forge/resolver": "1.8.0",
21
21
  "@types/history": "^4.7.11",
22
- "@forge/manifest": "12.6.0-next.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"