@forge/manifest 3.3.0-next.4 → 3.3.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @forge/manifest
2
2
 
3
+ ## 3.3.0-next.5
4
+
5
+ ### Minor Changes
6
+
7
+ - e95919f: Added blob csp support for script content permissions with manifest validation
8
+
9
+ ### Patch Changes
10
+
11
+ - f894871: Update manifest definitions
12
+
3
13
  ## 3.3.0-next.4
4
14
 
5
15
  ### Patch Changes
@@ -1301,6 +1301,54 @@
1301
1301
  "maxLength": 255,
1302
1302
  "pattern": "^[a-zA-Z0-9-_]+$"
1303
1303
  },
1304
+ "expression": {
1305
+ "type": "string"
1306
+ },
1307
+ "errorMessage": {
1308
+ "type": "string"
1309
+ },
1310
+ "view": {
1311
+ "type": "object",
1312
+ "properties": {
1313
+ "resource": {
1314
+ "type": "string",
1315
+ "minLength": 1,
1316
+ "maxLength": 23,
1317
+ "pattern": "^[a-zA-Z0-9_\\-]+$"
1318
+ }
1319
+ },
1320
+ "required": [
1321
+ "resource"
1322
+ ]
1323
+ },
1324
+ "edit": {
1325
+ "type": "object",
1326
+ "properties": {
1327
+ "resource": {
1328
+ "type": "string",
1329
+ "minLength": 1,
1330
+ "maxLength": 23,
1331
+ "pattern": "^[a-zA-Z0-9_\\-]+$"
1332
+ }
1333
+ },
1334
+ "required": [
1335
+ "resource"
1336
+ ]
1337
+ },
1338
+ "create": {
1339
+ "type": "object",
1340
+ "properties": {
1341
+ "resource": {
1342
+ "type": "string",
1343
+ "minLength": 1,
1344
+ "maxLength": 23,
1345
+ "pattern": "^[a-zA-Z0-9_\\-]+$"
1346
+ }
1347
+ },
1348
+ "required": [
1349
+ "resource"
1350
+ ]
1351
+ },
1304
1352
  "key": {
1305
1353
  "$ref": "#/definitions/ModuleKeySchema"
1306
1354
  }
@@ -1436,6 +1484,35 @@
1436
1484
  "function"
1437
1485
  ]
1438
1486
  },
1487
+ "searchSuggestions": {
1488
+ "anyOf": [
1489
+ {
1490
+ "type": "object",
1491
+ "properties": {
1492
+ "function": {
1493
+ "type": "string",
1494
+ "minLength": 1,
1495
+ "maxLength": 255,
1496
+ "pattern": "^[a-zA-Z0-9-_]+$"
1497
+ }
1498
+ },
1499
+ "required": [
1500
+ "function"
1501
+ ]
1502
+ },
1503
+ {
1504
+ "type": "object",
1505
+ "properties": {
1506
+ "expression": {
1507
+ "type": "string"
1508
+ }
1509
+ },
1510
+ "required": [
1511
+ "expression"
1512
+ ]
1513
+ }
1514
+ ]
1515
+ },
1439
1516
  "displayConditions": {
1440
1517
  "type": "object",
1441
1518
  "properties": {}
@@ -1570,6 +1647,35 @@
1570
1647
  "function"
1571
1648
  ]
1572
1649
  },
1650
+ "searchSuggestions": {
1651
+ "anyOf": [
1652
+ {
1653
+ "type": "object",
1654
+ "properties": {
1655
+ "function": {
1656
+ "type": "string",
1657
+ "minLength": 1,
1658
+ "maxLength": 255,
1659
+ "pattern": "^[a-zA-Z0-9-_]+$"
1660
+ }
1661
+ },
1662
+ "required": [
1663
+ "function"
1664
+ ]
1665
+ },
1666
+ {
1667
+ "type": "object",
1668
+ "properties": {
1669
+ "expression": {
1670
+ "type": "string"
1671
+ }
1672
+ },
1673
+ "required": [
1674
+ "expression"
1675
+ ]
1676
+ }
1677
+ ]
1678
+ },
1573
1679
  "displayConditions": {
1574
1680
  "type": "object",
1575
1681
  "properties": {}
@@ -1698,6 +1804,35 @@
1698
1804
  "function"
1699
1805
  ]
1700
1806
  },
1807
+ "searchSuggestions": {
1808
+ "anyOf": [
1809
+ {
1810
+ "type": "object",
1811
+ "properties": {
1812
+ "function": {
1813
+ "type": "string",
1814
+ "minLength": 1,
1815
+ "maxLength": 255,
1816
+ "pattern": "^[a-zA-Z0-9-_]+$"
1817
+ }
1818
+ },
1819
+ "required": [
1820
+ "function"
1821
+ ]
1822
+ },
1823
+ {
1824
+ "type": "object",
1825
+ "properties": {
1826
+ "expression": {
1827
+ "type": "string"
1828
+ }
1829
+ },
1830
+ "required": [
1831
+ "expression"
1832
+ ]
1833
+ }
1834
+ ]
1835
+ },
1701
1836
  "icon": {
1702
1837
  "type": "string",
1703
1838
  "minLength": 1,
@@ -1883,6 +2018,35 @@
1883
2018
  "function"
1884
2019
  ]
1885
2020
  },
2021
+ "searchSuggestions": {
2022
+ "anyOf": [
2023
+ {
2024
+ "type": "object",
2025
+ "properties": {
2026
+ "function": {
2027
+ "type": "string",
2028
+ "minLength": 1,
2029
+ "maxLength": 255,
2030
+ "pattern": "^[a-zA-Z0-9-_]+$"
2031
+ }
2032
+ },
2033
+ "required": [
2034
+ "function"
2035
+ ]
2036
+ },
2037
+ {
2038
+ "type": "object",
2039
+ "properties": {
2040
+ "expression": {
2041
+ "type": "string"
2042
+ }
2043
+ },
2044
+ "required": [
2045
+ "expression"
2046
+ ]
2047
+ }
2048
+ ]
2049
+ },
1886
2050
  "icon": {
1887
2051
  "type": "string",
1888
2052
  "minLength": 1,
@@ -764,6 +764,20 @@ export interface Modules {
764
764
  name: string;
765
765
  description: string;
766
766
  function?: string;
767
+ expression?: string;
768
+ errorMessage?: string;
769
+ view?: {
770
+ resource: string;
771
+ [k: string]: unknown;
772
+ };
773
+ edit?: {
774
+ resource: string;
775
+ [k: string]: unknown;
776
+ };
777
+ create?: {
778
+ resource: string;
779
+ [k: string]: unknown;
780
+ };
767
781
  key: ModuleKeySchema;
768
782
  [k: string]: unknown;
769
783
  },
@@ -771,6 +785,20 @@ export interface Modules {
771
785
  name: string;
772
786
  description: string;
773
787
  function?: string;
788
+ expression?: string;
789
+ errorMessage?: string;
790
+ view?: {
791
+ resource: string;
792
+ [k: string]: unknown;
793
+ };
794
+ edit?: {
795
+ resource: string;
796
+ [k: string]: unknown;
797
+ };
798
+ create?: {
799
+ resource: string;
800
+ [k: string]: unknown;
801
+ };
774
802
  key: ModuleKeySchema;
775
803
  [k: string]: unknown;
776
804
  }[]
@@ -808,6 +836,15 @@ export interface Modules {
808
836
  function: string;
809
837
  [k: string]: unknown;
810
838
  };
839
+ searchSuggestions?:
840
+ | {
841
+ function: string;
842
+ [k: string]: unknown;
843
+ }
844
+ | {
845
+ expression: string;
846
+ [k: string]: unknown;
847
+ };
811
848
  displayConditions?: {
812
849
  [k: string]: unknown;
813
850
  };
@@ -848,6 +885,15 @@ export interface Modules {
848
885
  function: string;
849
886
  [k: string]: unknown;
850
887
  };
888
+ searchSuggestions?:
889
+ | {
890
+ function: string;
891
+ [k: string]: unknown;
892
+ }
893
+ | {
894
+ expression: string;
895
+ [k: string]: unknown;
896
+ };
851
897
  displayConditions?: {
852
898
  [k: string]: unknown;
853
899
  };
@@ -887,6 +933,15 @@ export interface Modules {
887
933
  function: string;
888
934
  [k: string]: unknown;
889
935
  };
936
+ searchSuggestions?:
937
+ | {
938
+ function: string;
939
+ [k: string]: unknown;
940
+ }
941
+ | {
942
+ expression: string;
943
+ [k: string]: unknown;
944
+ };
890
945
  displayConditions?: {
891
946
  [k: string]: unknown;
892
947
  };
@@ -927,6 +982,15 @@ export interface Modules {
927
982
  function: string;
928
983
  [k: string]: unknown;
929
984
  };
985
+ searchSuggestions?:
986
+ | {
987
+ function: string;
988
+ [k: string]: unknown;
989
+ }
990
+ | {
991
+ expression: string;
992
+ [k: string]: unknown;
993
+ };
930
994
  displayConditions?: {
931
995
  [k: string]: unknown;
932
996
  };
@@ -965,6 +1029,15 @@ export interface Modules {
965
1029
  function: string;
966
1030
  [k: string]: unknown;
967
1031
  };
1032
+ searchSuggestions?:
1033
+ | {
1034
+ function: string;
1035
+ [k: string]: unknown;
1036
+ }
1037
+ | {
1038
+ expression: string;
1039
+ [k: string]: unknown;
1040
+ };
968
1041
  icon?: string;
969
1042
  resolver?: {
970
1043
  function: string;
@@ -1017,6 +1090,15 @@ export interface Modules {
1017
1090
  function: string;
1018
1091
  [k: string]: unknown;
1019
1092
  };
1093
+ searchSuggestions?:
1094
+ | {
1095
+ function: string;
1096
+ [k: string]: unknown;
1097
+ }
1098
+ | {
1099
+ expression: string;
1100
+ [k: string]: unknown;
1101
+ };
1020
1102
  icon?: string;
1021
1103
  resolver?: {
1022
1104
  function: string;
@@ -1068,6 +1150,15 @@ export interface Modules {
1068
1150
  function: string;
1069
1151
  [k: string]: unknown;
1070
1152
  };
1153
+ searchSuggestions?:
1154
+ | {
1155
+ function: string;
1156
+ [k: string]: unknown;
1157
+ }
1158
+ | {
1159
+ expression: string;
1160
+ [k: string]: unknown;
1161
+ };
1071
1162
  icon?: string;
1072
1163
  resolver?: {
1073
1164
  function: string;
@@ -1120,6 +1211,15 @@ export interface Modules {
1120
1211
  function: string;
1121
1212
  [k: string]: unknown;
1122
1213
  };
1214
+ searchSuggestions?:
1215
+ | {
1216
+ function: string;
1217
+ [k: string]: unknown;
1218
+ }
1219
+ | {
1220
+ expression: string;
1221
+ [k: string]: unknown;
1222
+ };
1123
1223
  icon?: string;
1124
1224
  resolver?: {
1125
1225
  function: string;
@@ -1,4 +1,4 @@
1
1
  export declare const EGRESS_TYPES: {
2
- EGRESS_SCRIPTS: string[];
2
+ ALLOWED_CSP_TYPES: string[];
3
3
  };
4
4
  //# sourceMappingURL=egress-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"egress-types.d.ts","sourceRoot":"","sources":["../../src/types/egress-types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;CAExB,CAAC"}
1
+ {"version":3,"file":"egress-types.d.ts","sourceRoot":"","sources":["../../src/types/egress-types.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY;;CAExB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EGRESS_TYPES = void 0;
4
+ const ALLOWED_CSP_UNSAFE_SOURCES = ['unsafe-eval', 'unsafe-hashes', 'unsafe-inline'];
5
+ const ALLOWED_CSP_SCHEMA_SOURCES = ['blob:'];
4
6
  exports.EGRESS_TYPES = {
5
- EGRESS_SCRIPTS: ['unsafe-eval', 'unsafe-hashes', 'unsafe-inline']
7
+ ALLOWED_CSP_TYPES: [...ALLOWED_CSP_UNSAFE_SOURCES, ...ALLOWED_CSP_SCHEMA_SOURCES]
6
8
  };
@@ -2,6 +2,12 @@ import { ManifestObject, ManifestValidationResult } from '../types';
2
2
  import { ManifestSchema } from '../schema/manifest';
3
3
  import { ValidatorInterface } from './validator-interface';
4
4
  export declare class PermissionsValidator implements ValidatorInterface<ManifestObject<ManifestSchema> | undefined, ManifestSchema> {
5
+ private validationErrors;
6
+ constructor();
7
+ private isValidURL;
8
+ private isValidHash;
9
+ private addValidationErrors;
10
+ private validateExternalPermissionURLs;
5
11
  validate(manifest: ManifestObject<ManifestSchema> | undefined): ManifestValidationResult<ManifestSchema>;
6
12
  }
7
13
  //# sourceMappingURL=permissions-validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permissions-validator.d.ts","sourceRoot":"","sources":["../../src/validators/permissions-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAmB,MAAM,UAAU,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAU,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,qBAAa,oBACX,YAAW,kBAAkB,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,EAAE,cAAc,CAAC;IACzF,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,GAAG,wBAAwB,CAAC,cAAc,CAAC;CAkIzG"}
1
+ {"version":3,"file":"permissions-validator.d.ts","sourceRoot":"","sources":["../../src/validators/permissions-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAmB,MAAM,UAAU,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAU,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM3D,qBAAa,oBACX,YAAW,kBAAkB,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,EAAE,cAAc,CAAC;IACzF,OAAO,CAAC,gBAAgB,CAAoB;;IAM5C,OAAO,CAAC,UAAU;IA+BlB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,8BAA8B;IAWtC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,SAAS,GAAG,wBAAwB,CAAC,cAAc,CAAC;CA8FzG"}
@@ -9,97 +9,100 @@ const url_1 = require("url");
9
9
  const shipyard_scopes_json_1 = tslib_1.__importDefault(require("../scopes/shipyard-scopes.json"));
10
10
  const deprecated_shipyard_scopes_json_1 = tslib_1.__importDefault(require("../scopes/deprecated-shipyard-scopes.json"));
11
11
  class PermissionsValidator {
12
- validate(manifest) {
13
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
14
- if (!manifest || !manifest.typedContent || !manifest.typedContent.permissions) {
15
- return {
16
- success: false,
17
- manifestObject: manifest
18
- };
12
+ constructor() {
13
+ this.validationErrors = [];
14
+ }
15
+ isValidURL(inputURL) {
16
+ const protocolRegex = /^(.*?:\/\/)/;
17
+ const validURI = /^(\*\.)?[.a-zA-Z0-9_\-\/:~#%?=&]+$/;
18
+ const allowedProtocols = ['https:', 'wss:'];
19
+ const MAX_URL_LENGTH = 1000;
20
+ if (inputURL.length > MAX_URL_LENGTH) {
21
+ return false;
19
22
  }
20
- const validationErrors = [];
21
- function addValidationError(element, value, manifest) {
22
- validationErrors.push(Object.assign({ message: text_1.errors.permissions.invalidPermission(element, value), reference: text_1.References.Permissions, level: 'error' }, utils_1.findPosition(value, manifest.yamlContentByLine)));
23
+ if (inputURL === '*') {
24
+ return true;
23
25
  }
26
+ if (!inputURL.includes('.') || inputURL.includes(' ')) {
27
+ return false;
28
+ }
29
+ try {
30
+ const domainOrUrlWithProtocol = protocolRegex.test(inputURL) ? inputURL : `https://${inputURL}`;
31
+ const parsedUrl = new url_1.URL(domainOrUrlWithProtocol);
32
+ if (!allowedProtocols.includes(parsedUrl.protocol)) {
33
+ return false;
34
+ }
35
+ return validURI.test(parsedUrl.hostname);
36
+ }
37
+ catch (_) {
38
+ return false;
39
+ }
40
+ }
41
+ isValidHash(cspString) {
24
42
  const BASE_64_HASH_PATTERNS = [
25
43
  /^sha256-[a-zA-Z0-9=+/]{44}$/,
26
44
  /^sha384-[a-zA-Z0-9=+/]{64}$/,
27
45
  /^sha512-[a-zA-Z0-9=+/]{88}$/
28
46
  ];
29
- function isValidHash(cspString) {
30
- return BASE_64_HASH_PATTERNS.some((pattern) => pattern.test(cspString));
47
+ return BASE_64_HASH_PATTERNS.some((pattern) => pattern.test(cspString));
48
+ }
49
+ addValidationErrors(element, values, manifest) {
50
+ values.forEach((value) => {
51
+ this.validationErrors.push(Object.assign({ message: text_1.errors.permissions.invalidPermission(element, value), reference: text_1.References.Permissions, level: 'error' }, utils_1.findPosition(value, manifest.yamlContentByLine)));
52
+ });
53
+ }
54
+ validateExternalPermissionURLs(extPermType, perms, manifest) {
55
+ const invalidPerms = perms === null || perms === void 0 ? void 0 : perms.filter((key) => !this.isValidURL(key));
56
+ if (invalidPerms === null || invalidPerms === void 0 ? void 0 : invalidPerms.length) {
57
+ this.addValidationErrors(extPermType, invalidPerms, manifest);
31
58
  }
32
- const validURI = /^(\*\.)?[.a-zA-Z0-9_\-\/:~#%?=&]+$/;
33
- const protocolRegex = /^(.*?:\/\/)/;
34
- const allowedProtocols = ['https:', 'wss:'];
35
- const MAX_URL_LENGTH = 1000;
36
- function isValidURL(inputURL) {
37
- if (inputURL.length > MAX_URL_LENGTH) {
38
- return false;
39
- }
40
- if (inputURL === '*') {
41
- return true;
42
- }
43
- if (!inputURL.includes('.') || inputURL.includes(' ')) {
44
- return false;
45
- }
46
- try {
47
- const domainOrUrlWithProtocol = protocolRegex.test(inputURL) ? inputURL : `https://${inputURL}`;
48
- const parsedUrl = new url_1.URL(domainOrUrlWithProtocol);
49
- if (!allowedProtocols.includes(parsedUrl.protocol)) {
50
- return false;
51
- }
52
- return validURI.test(parsedUrl.hostname);
53
- }
54
- catch (_) {
55
- return false;
56
- }
59
+ }
60
+ validate(manifest) {
61
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
62
+ if (!manifest || !manifest.typedContent || !manifest.typedContent.permissions) {
63
+ return {
64
+ success: false,
65
+ manifestObject: manifest
66
+ };
57
67
  }
58
68
  const ALL_SCOPES = shipyard_scopes_json_1.default.concat(deprecated_shipyard_scopes_json_1.default);
59
- const invalidScope = (_a = manifest.typedContent.permissions.scopes) === null || _a === void 0 ? void 0 : _a.find((key) => !ALL_SCOPES.includes(key));
60
- if (invalidScope) {
61
- addValidationError('scopes', invalidScope, manifest);
69
+ const invalidScopes = (_a = manifest.typedContent.permissions.scopes) === null || _a === void 0 ? void 0 : _a.filter((key) => !ALL_SCOPES.includes(key));
70
+ if (invalidScopes === null || invalidScopes === void 0 ? void 0 : invalidScopes.length) {
71
+ this.addValidationErrors('scopes', invalidScopes, manifest);
62
72
  }
63
- const invalidScripts = (_c = (_b = manifest.typedContent.permissions.content) === null || _b === void 0 ? void 0 : _b.scripts) === null || _c === void 0 ? void 0 : _c.find((key) => !egress_types_1.EGRESS_TYPES.EGRESS_SCRIPTS.includes(key) && !isValidHash(key));
64
- if (invalidScripts) {
65
- addValidationError('content.scripts', invalidScripts, manifest);
73
+ const invalidScripts = (_c = (_b = manifest.typedContent.permissions.content) === null || _b === void 0 ? void 0 : _b.scripts) === null || _c === void 0 ? void 0 : _c.filter((key) => !egress_types_1.EGRESS_TYPES.ALLOWED_CSP_TYPES.includes(key) && !this.isValidHash(key));
74
+ if (invalidScripts === null || invalidScripts === void 0 ? void 0 : invalidScripts.length) {
75
+ this.addValidationErrors('content.scripts', invalidScripts, manifest);
66
76
  }
67
- const invalidBackendString = (_f = (_e = (_d = manifest.typedContent.permissions.external) === null || _d === void 0 ? void 0 : _d.fetch) === null || _e === void 0 ? void 0 : _e.backend) === null || _f === void 0 ? void 0 : _f.filter((item) => typeof item === 'string').find((key) => !isValidURL(key));
68
- if (invalidBackendString) {
69
- addValidationError('external.fetch.backend', invalidBackendString, manifest);
77
+ const invalidBackendStrings = (_f = (_e = (_d = manifest.typedContent.permissions.external) === null || _d === void 0 ? void 0 : _d.fetch) === null || _e === void 0 ? void 0 : _e.backend) === null || _f === void 0 ? void 0 : _f.filter((item) => typeof item === 'string' && !this.isValidURL(item));
78
+ if (invalidBackendStrings === null || invalidBackendStrings === void 0 ? void 0 : invalidBackendStrings.length) {
79
+ this.addValidationErrors('external.fetch.backend', invalidBackendStrings, manifest);
70
80
  }
71
81
  const remoteMap = (_g = manifest.typedContent.remotes) === null || _g === void 0 ? void 0 : _g.reduce((prev, item) => prev.set(item.key, item.baseUrl), new Map());
72
- const invalidBackendRemote = (_k = (_j = (_h = manifest.typedContent.permissions.external) === null || _h === void 0 ? void 0 : _h.fetch) === null || _j === void 0 ? void 0 : _j.backend) === null || _k === void 0 ? void 0 : _k.filter((item) => typeof item === 'object').find((item) => !remoteMap || !remoteMap.has(item.remote) || !isValidURL(remoteMap.get(item.remote)));
73
- if (invalidBackendRemote) {
74
- addValidationError('external.fetch.backend', invalidBackendRemote.remote, manifest);
75
- }
76
- const invalidClientString = (_o = (_m = (_l = manifest.typedContent.permissions.external) === null || _l === void 0 ? void 0 : _l.fetch) === null || _m === void 0 ? void 0 : _m.client) === null || _o === void 0 ? void 0 : _o.filter((item) => typeof item === 'string').find((key) => !isValidURL(key));
77
- if (invalidClientString) {
78
- addValidationError('external.fetch.client', invalidClientString, manifest);
79
- }
80
- const invalidClient = (_r = (_q = (_p = manifest.typedContent.permissions.external) === null || _p === void 0 ? void 0 : _p.fetch) === null || _q === void 0 ? void 0 : _q.client) === null || _r === void 0 ? void 0 : _r.filter((item) => typeof item === 'object').find((item) => !remoteMap || !remoteMap.has(item.remote) || !isValidURL(remoteMap.get(item.remote)));
81
- if (invalidClient) {
82
- addValidationError('external.fetch.client', invalidClient.remote, manifest);
83
- }
84
- const invalidNavigation = (_t = (_s = manifest.typedContent.permissions.external) === null || _s === void 0 ? void 0 : _s.navigation) === null || _t === void 0 ? void 0 : _t.find((key) => !isValidURL(key));
85
- if (invalidNavigation) {
86
- addValidationError('external.navigation', invalidNavigation, manifest);
87
- }
88
- const invalidImages = (_v = (_u = manifest.typedContent.permissions.external) === null || _u === void 0 ? void 0 : _u.images) === null || _v === void 0 ? void 0 : _v.find((key) => !isValidURL(key));
89
- if (invalidImages) {
90
- addValidationError('external.images', invalidImages, manifest);
82
+ const invalidBackendRemotes = (_k = (_j = (_h = manifest.typedContent.permissions.external) === null || _h === void 0 ? void 0 : _h.fetch) === null || _j === void 0 ? void 0 : _j.backend) === null || _k === void 0 ? void 0 : _k.filter((item) => typeof item === 'object' &&
83
+ (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote)))).map((item) => item.remote);
84
+ if (invalidBackendRemotes === null || invalidBackendRemotes === void 0 ? void 0 : invalidBackendRemotes.length) {
85
+ this.addValidationErrors('external.fetch.backend', invalidBackendRemotes, manifest);
91
86
  }
92
- const invalidMedia = (_x = (_w = manifest.typedContent.permissions.external) === null || _w === void 0 ? void 0 : _w.media) === null || _x === void 0 ? void 0 : _x.find((key) => !isValidURL(key));
93
- if (invalidMedia) {
94
- addValidationError('external.media', invalidMedia, manifest);
87
+ const invalidClientStrings = (_o = (_m = (_l = manifest.typedContent.permissions.external) === null || _l === void 0 ? void 0 : _l.fetch) === null || _m === void 0 ? void 0 : _m.client) === null || _o === void 0 ? void 0 : _o.filter((item) => typeof item === 'string' && !this.isValidURL(item));
88
+ if (invalidClientStrings) {
89
+ this.addValidationErrors('external.fetch.client', invalidClientStrings, manifest);
95
90
  }
96
- const invalidExternalScripts = (_z = (_y = manifest.typedContent.permissions.external) === null || _y === void 0 ? void 0 : _y.scripts) === null || _z === void 0 ? void 0 : _z.find((key) => !isValidURL(key));
97
- if (invalidExternalScripts) {
98
- addValidationError('external.scripts', invalidExternalScripts, manifest);
91
+ const invalidClients = (_r = (_q = (_p = manifest.typedContent.permissions.external) === null || _p === void 0 ? void 0 : _p.fetch) === null || _q === void 0 ? void 0 : _q.client) === null || _r === void 0 ? void 0 : _r.filter((item) => typeof item === 'object' &&
92
+ (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote)))).map((item) => item.remote);
93
+ if (invalidClients) {
94
+ this.addValidationErrors('external.fetch.client', invalidClients, manifest);
99
95
  }
96
+ this.validateExternalPermissionURLs('external.navigation', (_s = manifest.typedContent.permissions.external) === null || _s === void 0 ? void 0 : _s.navigation, manifest);
97
+ this.validateExternalPermissionURLs('external.images', (_t = manifest.typedContent.permissions.external) === null || _t === void 0 ? void 0 : _t.images, manifest);
98
+ this.validateExternalPermissionURLs('external.frames', (_u = manifest.typedContent.permissions.external) === null || _u === void 0 ? void 0 : _u.frames, manifest);
99
+ this.validateExternalPermissionURLs('external.scripts', (_v = manifest.typedContent.permissions.external) === null || _v === void 0 ? void 0 : _v.scripts, manifest);
100
+ this.validateExternalPermissionURLs('external.styles', (_w = manifest.typedContent.permissions.external) === null || _w === void 0 ? void 0 : _w.styles, manifest);
101
+ this.validateExternalPermissionURLs('external.media', (_x = manifest.typedContent.permissions.external) === null || _x === void 0 ? void 0 : _x.media, manifest);
102
+ this.validateExternalPermissionURLs('external.fonts', (_y = manifest.typedContent.permissions.external) === null || _y === void 0 ? void 0 : _y.fonts, manifest);
100
103
  return {
101
- success: validationErrors.length === 0,
102
- errors: validationErrors
104
+ success: this.validationErrors.length === 0,
105
+ errors: this.validationErrors
103
106
  };
104
107
  }
105
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/manifest",
3
- "version": "3.3.0-next.4",
3
+ "version": "3.3.0-next.5",
4
4
  "description": "Definitions and validations of the Forge manifest",
5
5
  "main": "out/index.js",
6
6
  "scripts": {