@forge/manifest 7.0.1-next.0 → 7.1.0

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 (46) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/out/builder/processor-builder.js +2 -1
  3. package/out/processor/abstract-validation-processor.js +2 -2
  4. package/out/scopes/index.js +6 -7
  5. package/out/text/errors.d.ts +1 -0
  6. package/out/text/errors.d.ts.map +1 -1
  7. package/out/text/errors.js +2 -1
  8. package/out/utils/index.d.ts +1 -0
  9. package/out/utils/index.d.ts.map +1 -1
  10. package/out/utils/index.js +1 -0
  11. package/out/utils/manifest-parser.d.ts +15 -0
  12. package/out/utils/manifest-parser.d.ts.map +1 -0
  13. package/out/utils/manifest-parser.js +42 -0
  14. package/out/utils/module-references.js +1 -1
  15. package/out/validators/app-features-validator.js +8 -4
  16. package/out/validators/connect-authentication-validator.js +8 -4
  17. package/out/validators/connect-modules-validator.js +18 -3
  18. package/out/validators/connect-remote-validator.js +16 -7
  19. package/out/validators/data-classification-validator.js +8 -5
  20. package/out/validators/display-conditions-validator.js +8 -7
  21. package/out/validators/entity-property-validator.js +9 -6
  22. package/out/validators/jql-function-validator.js +9 -6
  23. package/out/validators/modules-validator.js +136 -49
  24. package/out/validators/modules-validators/bitbucket/validateBackendModuleEndpoints.js +16 -8
  25. package/out/validators/modules-validators/confluence/validateCrossModulePropertyUniqueness.js +6 -2
  26. package/out/validators/modules-validators/confluence/validateCustomContentHierarchy.js +12 -2
  27. package/out/validators/modules-validators/confluence/validateKeyboardShortcuts.js +7 -2
  28. package/out/validators/modules-validators/confluence/validatePropertyUniqueness.js +6 -2
  29. package/out/validators/modules-validators/confluence/validateSingleProperty.js +6 -1
  30. package/out/validators/modules-validators/jira/ui-modifications.js +6 -1
  31. package/out/validators/modules-validators/jira/validate-full-admin-page.js +21 -11
  32. package/out/validators/modules-validators/jira/validate-subpages-in-module.js +12 -2
  33. package/out/validators/modules-validators/remote/validate-storage-operation.js +8 -4
  34. package/out/validators/modules-validators/validateModuleScopes.js +7 -2
  35. package/out/validators/package-validator.js +1 -2
  36. package/out/validators/permissions-validator.js +32 -24
  37. package/out/validators/product-trigger-scopes-validator.js +11 -6
  38. package/out/validators/providers-validator.js +35 -16
  39. package/out/validators/resources-validator.js +54 -15
  40. package/out/validators/schema-validator.js +104 -84
  41. package/out/validators/snapshot-validator.js +3 -4
  42. package/out/validators/storage-validator.js +41 -14
  43. package/out/validators/yaml-validator.d.ts +2 -0
  44. package/out/validators/yaml-validator.d.ts.map +1 -1
  45. package/out/validators/yaml-validator.js +10 -6
  46. package/package.json +3 -2
@@ -45,17 +45,21 @@ class PermissionsValidator {
45
45
  }
46
46
  addValidationErrors(result, element, values, manifest) {
47
47
  values.forEach((value) => {
48
- result.push(Object.assign({ message: text_1.errors.permissions.invalidPermission(element, value), reference: text_1.References.Permissions, level: 'error' }, (0, utils_1.findPosition)(value, manifest.yamlContentByLine)));
48
+ result.push({
49
+ message: text_1.errors.permissions.invalidPermission(element, value),
50
+ reference: text_1.References.Permissions,
51
+ level: 'error',
52
+ ...(0, utils_1.findPosition)(value, manifest.yamlContentByLine)
53
+ });
49
54
  });
50
55
  }
51
56
  validateExternalPermissionURLs(result, extPermType, perms, manifest) {
52
- const invalidPerms = perms === null || perms === void 0 ? void 0 : perms.filter((key) => !this.isValidURL(key));
53
- if (invalidPerms === null || invalidPerms === void 0 ? void 0 : invalidPerms.length) {
57
+ const invalidPerms = perms?.filter((key) => !this.isValidURL(key));
58
+ if (invalidPerms?.length) {
54
59
  this.addValidationErrors(result, extPermType, invalidPerms, manifest);
55
60
  }
56
61
  }
57
62
  async validate(manifest) {
58
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
59
63
  if (!manifest || !manifest.typedContent || !manifest.typedContent.permissions) {
60
64
  return {
61
65
  success: false,
@@ -64,40 +68,44 @@ class PermissionsValidator {
64
68
  }
65
69
  const errors = [];
66
70
  const ALL_SCOPES = shipyard_scopes_json_1.default.concat(deprecated_shipyard_scopes_json_1.default);
67
- const invalidScopes = (_a = manifest.typedContent.permissions.scopes) === null || _a === void 0 ? void 0 : _a.filter((key) => !ALL_SCOPES.includes(key));
68
- if (invalidScopes === null || invalidScopes === void 0 ? void 0 : invalidScopes.length) {
71
+ const invalidScopes = manifest.typedContent.permissions.scopes?.filter((key) => !ALL_SCOPES.includes(key));
72
+ if (invalidScopes?.length) {
69
73
  this.addValidationErrors(errors, 'scopes', invalidScopes, manifest);
70
74
  }
71
- 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));
72
- if (invalidScripts === null || invalidScripts === void 0 ? void 0 : invalidScripts.length) {
75
+ const invalidScripts = manifest.typedContent.permissions.content?.scripts?.filter((key) => !egress_types_1.EGRESS_TYPES.ALLOWED_CSP_TYPES.includes(key) && !this.isValidHash(key));
76
+ if (invalidScripts?.length) {
73
77
  this.addValidationErrors(errors, 'content.scripts', invalidScripts, manifest);
74
78
  }
75
- 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));
76
- if (invalidBackendStrings === null || invalidBackendStrings === void 0 ? void 0 : invalidBackendStrings.length) {
79
+ const invalidBackendStrings = manifest.typedContent.permissions.external?.fetch?.backend?.filter((item) => typeof item === 'string' && !this.isValidURL(item));
80
+ if (invalidBackendStrings?.length) {
77
81
  this.addValidationErrors(errors, 'external.fetch.backend', invalidBackendStrings, manifest);
78
82
  }
79
- const remoteMap = (_g = manifest.typedContent.remotes) === null || _g === void 0 ? void 0 : _g.reduce((prev, item) => prev.set(item.key, item.baseUrl), new Map());
80
- 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' &&
81
- (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote)))).map((item) => item.remote);
82
- if (invalidBackendRemotes === null || invalidBackendRemotes === void 0 ? void 0 : invalidBackendRemotes.length) {
83
+ const remoteMap = manifest.typedContent.remotes?.reduce((prev, item) => prev.set(item.key, item.baseUrl), new Map());
84
+ const invalidBackendRemotes = manifest.typedContent.permissions.external?.fetch?.backend
85
+ ?.filter((item) => typeof item === 'object' &&
86
+ (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote))))
87
+ .map((item) => item.remote);
88
+ if (invalidBackendRemotes?.length) {
83
89
  this.addValidationErrors(errors, 'external.fetch.backend', invalidBackendRemotes, manifest);
84
90
  }
85
- 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));
91
+ const invalidClientStrings = manifest.typedContent.permissions.external?.fetch?.client?.filter((item) => typeof item === 'string' && !this.isValidURL(item));
86
92
  if (invalidClientStrings) {
87
93
  this.addValidationErrors(errors, 'external.fetch.client', invalidClientStrings, manifest);
88
94
  }
89
- 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' &&
90
- (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote)))).map((item) => item.remote);
95
+ const invalidClients = manifest.typedContent.permissions.external?.fetch?.client
96
+ ?.filter((item) => typeof item === 'object' &&
97
+ (!remoteMap || !remoteMap.has(item.remote) || !this.isValidURL(remoteMap.get(item.remote))))
98
+ .map((item) => item.remote);
91
99
  if (invalidClients) {
92
100
  this.addValidationErrors(errors, 'external.fetch.client', invalidClients, manifest);
93
101
  }
94
- this.validateExternalPermissionURLs(errors, 'external.navigation', (_s = manifest.typedContent.permissions.external) === null || _s === void 0 ? void 0 : _s.navigation, manifest);
95
- this.validateExternalPermissionURLs(errors, 'external.images', (_t = manifest.typedContent.permissions.external) === null || _t === void 0 ? void 0 : _t.images, manifest);
96
- this.validateExternalPermissionURLs(errors, 'external.frames', (_u = manifest.typedContent.permissions.external) === null || _u === void 0 ? void 0 : _u.frames, manifest);
97
- this.validateExternalPermissionURLs(errors, 'external.scripts', (_v = manifest.typedContent.permissions.external) === null || _v === void 0 ? void 0 : _v.scripts, manifest);
98
- this.validateExternalPermissionURLs(errors, 'external.styles', (_w = manifest.typedContent.permissions.external) === null || _w === void 0 ? void 0 : _w.styles, manifest);
99
- this.validateExternalPermissionURLs(errors, 'external.media', (_x = manifest.typedContent.permissions.external) === null || _x === void 0 ? void 0 : _x.media, manifest);
100
- this.validateExternalPermissionURLs(errors, 'external.fonts', (_y = manifest.typedContent.permissions.external) === null || _y === void 0 ? void 0 : _y.fonts, manifest);
102
+ this.validateExternalPermissionURLs(errors, 'external.navigation', manifest.typedContent.permissions.external?.navigation, manifest);
103
+ this.validateExternalPermissionURLs(errors, 'external.images', manifest.typedContent.permissions.external?.images, manifest);
104
+ this.validateExternalPermissionURLs(errors, 'external.frames', manifest.typedContent.permissions.external?.frames, manifest);
105
+ this.validateExternalPermissionURLs(errors, 'external.scripts', manifest.typedContent.permissions.external?.scripts, manifest);
106
+ this.validateExternalPermissionURLs(errors, 'external.styles', manifest.typedContent.permissions.external?.styles, manifest);
107
+ this.validateExternalPermissionURLs(errors, 'external.media', manifest.typedContent.permissions.external?.media, manifest);
108
+ this.validateExternalPermissionURLs(errors, 'external.fonts', manifest.typedContent.permissions.external?.fonts, manifest);
101
109
  return {
102
110
  success: errors.length === 0,
103
111
  errors
@@ -5,11 +5,11 @@ const text_1 = require("../text");
5
5
  const utils_1 = require("../utils");
6
6
  const scopes_1 = require("../scopes");
7
7
  class ProductTriggerScopesValidator {
8
+ config;
8
9
  constructor(config) {
9
10
  this.config = config;
10
11
  }
11
12
  async validate(manifest) {
12
- var _a;
13
13
  if (!manifest || !manifest.typedContent) {
14
14
  return {
15
15
  success: false,
@@ -18,14 +18,19 @@ class ProductTriggerScopesValidator {
18
18
  }
19
19
  const validationErrors = [];
20
20
  const getRequiredScopes = (productEvent) => {
21
- var _a;
22
21
  const emptyRequiredScopes = { current: [] };
23
- return (((_a = this.config.mapping.find((value) => value.productEvent == productEvent)) === null || _a === void 0 ? void 0 : _a.oAuthScopes) || emptyRequiredScopes);
22
+ return (this.config.mapping.find((value) => value.productEvent == productEvent)?.oAuthScopes || emptyRequiredScopes);
24
23
  };
25
24
  const addValidationError = (scope, event) => {
26
- validationErrors.push(Object.assign({ message: text_1.errors.permissions.missingPermissionFromScope(scope, event), reference: text_1.References.MissingScopes, level: 'error', metadata: {
25
+ validationErrors.push({
26
+ message: text_1.errors.permissions.missingPermissionFromScope(scope, event),
27
+ reference: text_1.References.MissingScopes,
28
+ level: 'error',
29
+ metadata: {
27
30
  missingPermission: scope
28
- } }, (0, utils_1.findPosition)('scopes', manifest.yamlContentByLine)));
31
+ },
32
+ ...(0, utils_1.findPosition)('scopes', manifest.yamlContentByLine)
33
+ });
29
34
  };
30
35
  if (!manifest.typedContent.modules || !manifest.typedContent.modules.trigger) {
31
36
  return {
@@ -33,7 +38,7 @@ class ProductTriggerScopesValidator {
33
38
  manifestObject: manifest
34
39
  };
35
40
  }
36
- const manifestScopes = ((_a = manifest.typedContent.permissions) === null || _a === void 0 ? void 0 : _a.scopes) || [];
41
+ const manifestScopes = manifest.typedContent.permissions?.scopes || [];
37
42
  for (const element of manifest.typedContent.modules.trigger) {
38
43
  for (const event of element.events) {
39
44
  const requiredScopes = getRequiredScopes(event);
@@ -15,28 +15,38 @@ class ProvidersValidator {
15
15
  const auth = manifest.typedContent.providers.auth;
16
16
  const remotes = manifest.typedContent.remotes;
17
17
  const permissions = manifest.typedContent.permissions;
18
- auth === null || auth === void 0 ? void 0 : auth.forEach((provider) => {
19
- var _a, _b;
18
+ auth?.forEach((provider) => {
20
19
  if ('remotes' in provider) {
21
- const hasMissing = (_a = provider.remotes) === null || _a === void 0 ? void 0 : _a.find((key) => !(remotes === null || remotes === void 0 ? void 0 : remotes.find((item) => item.key === key)));
20
+ const hasMissing = provider.remotes?.find((key) => !remotes?.find((item) => item.key === key));
22
21
  if (hasMissing) {
23
- validationErrors.push(Object.assign({ message: text_1.errors.providers.missingRemote(provider.key, hasMissing), reference: text_1.References.Providers, level: 'error' }, (0, utils_1.findPosition)(hasMissing, manifest.yamlContentByLine)));
22
+ validationErrors.push({
23
+ message: text_1.errors.providers.missingRemote(provider.key, hasMissing),
24
+ reference: text_1.References.Providers,
25
+ level: 'error',
26
+ ...(0, utils_1.findPosition)(hasMissing, manifest.yamlContentByLine)
27
+ });
24
28
  }
25
- const missingEgressPermission = (_b = provider.remotes) === null || _b === void 0 ? void 0 : _b.find((key) => {
26
- var _a, _b, _c;
27
- const remote = remotes === null || remotes === void 0 ? void 0 : remotes.find((item) => item.key === key);
29
+ const missingEgressPermission = provider.remotes?.find((key) => {
30
+ const remote = remotes?.find((item) => item.key === key);
28
31
  if (remote) {
29
- const egressPermission = (_c = (_b = (_a = permissions === null || permissions === void 0 ? void 0 : permissions.external) === null || _a === void 0 ? void 0 : _a.fetch) === null || _b === void 0 ? void 0 : _b.backend) === null || _c === void 0 ? void 0 : _c.find((item) => typeof item === 'string' ? item === remote.baseUrl : item.remote === remote.key);
32
+ const egressPermission = permissions?.external?.fetch?.backend?.find((item) => typeof item === 'string' ? item === remote.baseUrl : item.remote === remote.key);
30
33
  return !egressPermission;
31
34
  }
32
35
  return false;
33
36
  });
34
37
  if (missingEgressPermission) {
35
- validationErrors.push(Object.assign({ message: text_1.errors.providers.missingEgress(missingEgressPermission), reference: text_1.References.Providers, level: 'error' }, (0, utils_1.findPosition)(missingEgressPermission, manifest.yamlContentByLine)));
38
+ validationErrors.push({
39
+ message: text_1.errors.providers.missingEgress(missingEgressPermission),
40
+ reference: text_1.References.Providers,
41
+ level: 'error',
42
+ ...(0, utils_1.findPosition)(missingEgressPermission, manifest.yamlContentByLine)
43
+ });
36
44
  }
37
45
  }
38
46
  });
39
- auth === null || auth === void 0 ? void 0 : auth.filter((provider) => 'actions' in provider).forEach((provider) => {
47
+ auth
48
+ ?.filter((provider) => 'actions' in provider)
49
+ .forEach((provider) => {
40
50
  Object.values(provider.actions).forEach((action) => {
41
51
  const message = action && this.isActionValidRemote(provider, action, manifest, remotes);
42
52
  if (message) {
@@ -44,7 +54,7 @@ class ProvidersValidator {
44
54
  }
45
55
  });
46
56
  });
47
- auth === null || auth === void 0 ? void 0 : auth.forEach((provider) => {
57
+ auth?.forEach((provider) => {
48
58
  const message = this.isValidProfileRetrieverFunction(provider, manifest);
49
59
  if (message) {
50
60
  validationErrors.push(message);
@@ -56,18 +66,27 @@ class ProvidersValidator {
56
66
  };
57
67
  }
58
68
  isActionValidRemote(provider, action, manifest, remotes) {
59
- const remote = remotes === null || remotes === void 0 ? void 0 : remotes.find((item) => item.key === (action === null || action === void 0 ? void 0 : action.remote));
69
+ const remote = remotes?.find((item) => item.key === action?.remote);
60
70
  if (action && !remote) {
61
- return Object.assign({ message: text_1.errors.providers.missingRemote(provider.key, action.remote), reference: text_1.References.Providers, level: 'error' }, (0, utils_1.findPosition)(action.remote, manifest.yamlContentByLine));
71
+ return {
72
+ message: text_1.errors.providers.missingRemote(provider.key, action.remote),
73
+ reference: text_1.References.Providers,
74
+ level: 'error',
75
+ ...(0, utils_1.findPosition)(action.remote, manifest.yamlContentByLine)
76
+ };
62
77
  }
63
78
  }
64
79
  isValidProfileRetrieverFunction(provider, manifest) {
65
- var _a, _b, _c;
66
80
  if ('actions' in provider && 'function' in provider.actions.retrieveProfile) {
67
81
  const { function: functionKey } = provider.actions.retrieveProfile;
68
- const hasFunction = (_c = (_b = (_a = manifest.typedContent) === null || _a === void 0 ? void 0 : _a.modules) === null || _b === void 0 ? void 0 : _b.function) === null || _c === void 0 ? void 0 : _c.find((func) => func.key === functionKey);
82
+ const hasFunction = manifest.typedContent?.modules?.function?.find((func) => func.key === functionKey);
69
83
  if (!hasFunction) {
70
- return Object.assign({ message: text_1.errors.providers.missingProfileFunction(provider.key, functionKey), reference: text_1.References.Providers, level: 'error' }, (0, utils_1.findPosition)(functionKey, manifest.yamlContentByLine));
84
+ return {
85
+ message: text_1.errors.providers.missingProfileFunction(provider.key, functionKey),
86
+ reference: text_1.References.Providers,
87
+ level: 'error',
88
+ ...(0, utils_1.findPosition)(functionKey, manifest.yamlContentByLine)
89
+ };
71
90
  }
72
91
  }
73
92
  }
@@ -26,16 +26,25 @@ class ResourcesValidator {
26
26
  };
27
27
  }
28
28
  if (resources.length > MAX_RESOURCE_COUNT) {
29
- validationErrors.push(Object.assign({ message: text_1.errors.resources.tooManyResourcesError(MAX_RESOURCE_COUNT), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)('resource', yamlContentByLine)));
29
+ validationErrors.push({
30
+ message: text_1.errors.resources.tooManyResourcesError(MAX_RESOURCE_COUNT),
31
+ reference: text_1.References.Resources,
32
+ level: 'error',
33
+ ...(0, utils_1.findPosition)('resource', yamlContentByLine)
34
+ });
30
35
  }
31
36
  if (modules) {
32
37
  const resourceMap = new Map(resources.map(({ key, path }) => [key, path]));
33
38
  const manifestDir = (0, path_1.dirname)(filePath);
34
39
  (0, utils_1.getValidModules)(modules).forEach((moduleKey) => {
35
- var _a;
36
- (_a = modules[moduleKey]) === null || _a === void 0 ? void 0 : _a.forEach((module) => {
40
+ modules[moduleKey]?.forEach((module) => {
37
41
  (0, utils_2.findInvalidResourceReferences)(module, resources).forEach((resourceKey) => {
38
- validationErrors.push(Object.assign({ message: text_1.errors.modules.wrongResourceReference(moduleKey, resourceKey), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)(moduleKey, yamlContentByLine)));
42
+ validationErrors.push({
43
+ message: text_1.errors.modules.wrongResourceReference(moduleKey, resourceKey),
44
+ reference: text_1.References.Resources,
45
+ level: 'error',
46
+ ...(0, utils_1.findPosition)(moduleKey, yamlContentByLine)
47
+ });
39
48
  });
40
49
  const resourcePath = resourceMap.get(module.resource);
41
50
  if (resourcePath === undefined)
@@ -43,16 +52,31 @@ class ResourcesValidator {
43
52
  const resourcePathDir = (0, path_1.resolve)(resourcePath);
44
53
  if (module.render === 'native') {
45
54
  if (fs_1.default.lstatSync(resourcePathDir).isDirectory()) {
46
- validationErrors.push(Object.assign({ message: text_1.errors.modules.wrongResourceType(resourcePath), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)(moduleKey, yamlContentByLine)));
55
+ validationErrors.push({
56
+ message: text_1.errors.modules.wrongResourceType(resourcePath),
57
+ reference: text_1.References.Resources,
58
+ level: 'error',
59
+ ...(0, utils_1.findPosition)(moduleKey, yamlContentByLine)
60
+ });
47
61
  }
48
62
  }
49
63
  else {
50
64
  if (fs_1.default.lstatSync(resourcePathDir).isDirectory() &&
51
65
  !fs_1.default.existsSync((0, path_1.resolve)(manifestDir, resourcePath, 'index.html'))) {
52
- validationErrors.push(Object.assign({ message: text_1.errors.resources.missingEntrypoint(resourcePath, moduleKey), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)(resourcePath, yamlContentByLine)));
66
+ validationErrors.push({
67
+ message: text_1.errors.resources.missingEntrypoint(resourcePath, moduleKey),
68
+ reference: text_1.References.Resources,
69
+ level: 'error',
70
+ ...(0, utils_1.findPosition)(resourcePath, yamlContentByLine)
71
+ });
53
72
  }
54
73
  else if (!fs_1.default.lstatSync(resourcePathDir).isDirectory()) {
55
- validationErrors.push(Object.assign({ message: text_1.errors.resources.nonDirectory(resourcePath, moduleKey), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)(resourcePath, yamlContentByLine)));
74
+ validationErrors.push({
75
+ message: text_1.errors.resources.nonDirectory(resourcePath, moduleKey),
76
+ reference: text_1.References.Resources,
77
+ level: 'error',
78
+ ...(0, utils_1.findPosition)(resourcePath, yamlContentByLine)
79
+ });
56
80
  }
57
81
  }
58
82
  });
@@ -60,7 +84,6 @@ class ResourcesValidator {
60
84
  (0, utils_1.getValidModules)(modules).forEach((moduleKey) => {
61
85
  const uniquePaths = new Set(modules[moduleKey].map(({ resource }) => resourceMap.get(resource)));
62
86
  uniquePaths.forEach((path) => {
63
- var _a, _b, _c;
64
87
  if (!path)
65
88
  return;
66
89
  if (fs_1.default.existsSync((0, path_1.resolve)(manifestDir, path, 'index.html'))) {
@@ -69,16 +92,22 @@ class ResourcesValidator {
69
92
  const cspContent = $('meta[http-equiv="Content-Security-Policy"]').attr('content');
70
93
  if (cspContent) {
71
94
  const cspStyleSrc = cspContent.split(';').find((s) => s.startsWith('style-src'));
72
- if (cspStyleSrc === null || cspStyleSrc === void 0 ? void 0 : cspStyleSrc.includes("'unsafe-inline'")) {
73
- const existingStylesPermissions = (_c = (_b = (_a = manifest.typedContent) === null || _a === void 0 ? void 0 : _a.permissions) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.styles;
95
+ if (cspStyleSrc?.includes("'unsafe-inline'")) {
96
+ const existingStylesPermissions = manifest.typedContent?.permissions?.content?.styles;
74
97
  let shouldShowError = false;
75
- if (!(existingStylesPermissions === null || existingStylesPermissions === void 0 ? void 0 : existingStylesPermissions.length) || !(existingStylesPermissions === null || existingStylesPermissions === void 0 ? void 0 : existingStylesPermissions.includes('unsafe-inline'))) {
98
+ if (!existingStylesPermissions?.length || !existingStylesPermissions?.includes('unsafe-inline')) {
76
99
  shouldShowError = true;
77
100
  }
78
101
  if (shouldShowError) {
79
- validationErrors.push(Object.assign({ message: text_1.errors.resources.deprecatedCspPolicyDefinition(path), reference: text_1.References.Resources, level: 'error', metadata: {
102
+ validationErrors.push({
103
+ message: text_1.errors.resources.deprecatedCspPolicyDefinition(path),
104
+ reference: text_1.References.Resources,
105
+ level: 'error',
106
+ metadata: {
80
107
  missingContentStylePermission: 'unsafe-inline'
81
- } }, (0, utils_1.findPosition)(path, yamlContentByLine)));
108
+ },
109
+ ...(0, utils_1.findPosition)(path, yamlContentByLine)
110
+ });
82
111
  }
83
112
  }
84
113
  }
@@ -92,10 +121,20 @@ class ResourcesValidator {
92
121
  const manifestDir = (0, path_1.dirname)(filePath);
93
122
  const resourceDirPath = (0, path_1.resolve)(manifestDir, path);
94
123
  if (!fs_1.default.existsSync(resourceDirPath)) {
95
- return Object.assign({ message: text_1.errors.resources.missingResource(path, key), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)(path, yamlContentByLine));
124
+ return {
125
+ message: text_1.errors.resources.missingResource(path, key),
126
+ reference: text_1.References.Resources,
127
+ level: 'error',
128
+ ...(0, utils_1.findPosition)(path, yamlContentByLine)
129
+ };
96
130
  }
97
131
  else if (fs_1.default.lstatSync(resourceDirPath).isDirectory() && fs_1.default.readdirSync(resourceDirPath).length === 0) {
98
- return Object.assign({ message: text_1.errors.resources.emptyDirectory(path, key), reference: text_1.References.Resources, level: 'error' }, (0, utils_1.findPosition)(path, yamlContentByLine));
132
+ return {
133
+ message: text_1.errors.resources.emptyDirectory(path, key),
134
+ reference: text_1.References.Resources,
135
+ level: 'error',
136
+ ...(0, utils_1.findPosition)(path, yamlContentByLine)
137
+ };
99
138
  }
100
139
  })
101
140
  .filter((error) => error !== undefined);
@@ -7,91 +7,87 @@ const ajv_formats_1 = tslib_1.__importDefault(require("ajv-formats"));
7
7
  const utils_1 = require("../utils");
8
8
  const text_1 = require("../text");
9
9
  class SchemaValidator {
10
+ schema;
11
+ validateSchema;
10
12
  constructor(schema) {
11
13
  this.schema = schema;
12
- this.processErrorMessage = (error) => {
13
- var _a;
14
- if (error.keyword === 'required' && error.schemaPath.includes('oneOf')) {
15
- return undefined;
16
- }
17
- if (error.keyword === 'not') {
18
- return text_1.errors.schema.notAllowed(error.schema.required);
19
- }
20
- if (error.keyword === 'enum') {
21
- return text_1.errors.schema.enumValues(error.params.allowedValues);
22
- }
23
- if (error.keyword === 'oneOf') {
24
- if (error.params.passingSchemas) {
25
- const requiredProps = error.params.passingSchemas.map((v) => error.schema[v].required);
26
- return text_1.errors.schema.oneOf(requiredProps);
27
- }
28
- else if ((_a = error.parentSchema) === null || _a === void 0 ? void 0 : _a.oneOf) {
29
- const requiredProps = error.parentSchema.oneOf
30
- .map((v) => v.required)
31
- .filter((v) => !!v);
32
- return text_1.errors.schema.oneOf(requiredProps);
33
- }
34
- return text_1.errors.schema.oneOf(undefined);
35
- }
36
- if (error.keyword === 'additionalProperties' && 'additionalProperty' in error.params) {
37
- return text_1.errors.schema.additionalProperties(error.params.additionalProperty);
38
- }
39
- return error.message;
40
- };
41
- this.handleModuleError = (path, error, manifest) => {
42
- const hasProperty = path.length > 1;
43
- const propertyName = path[path.length - 1];
44
- const errorMessage = this.processErrorMessage(error);
45
- if (!errorMessage) {
46
- return undefined;
47
- }
48
- if (hasProperty) {
49
- path.splice(path.length - 1, 0, 'property');
50
- }
51
- const data = typeof error.data !== 'string' ? undefined : error.data;
52
- const searchString = data && hasProperty ? `${propertyName}: ${data}` : path[0];
53
- return Object.assign({ message: text_1.errors.schemaError(data, path, errorMessage), reference: text_1.References.SchemaError, level: 'error' }, (0, utils_1.findPosition)(searchString, manifest.yamlContentByLine));
54
- };
55
- this.handleGenericError = (path, error, manifest) => {
56
- const hasProperty = path.length > 1;
57
- const propertyName = path[path.length - 1];
58
- const errorMessage = this.processErrorMessage(error);
59
- if (!errorMessage) {
60
- return undefined;
61
- }
62
- if (hasProperty) {
63
- path.splice(path.length - 1, 0, 'property');
64
- }
65
- const data = typeof error.data !== 'string' ? undefined : error.data;
66
- const searchString = error.data && hasProperty ? `${propertyName}: ${error.data}` : propertyName;
67
- return Object.assign({ message: text_1.errors.schemaError(data, path, errorMessage), reference: text_1.References.SchemaError, level: 'error' }, (0, utils_1.findPosition)(searchString, manifest.yamlContentByLine));
68
- };
69
- this.isDeprecatedField = (section, error) => {
70
- if (error.keyword === 'additionalProperties') {
71
- return section === 'app' && error.params.additionalProperty === 'name';
72
- }
73
- return false;
74
- };
75
- this.handleDeprecatedField = (section, error, manifest) => {
76
- const property = error.params.additionalProperty;
77
- return Object.assign({ message: text_1.errors.schema.deprecatedValue(section, property, this.getDeprecationInfo(section, property)), reference: text_1.References.Deprecated, level: 'warning' }, (0, utils_1.findPosition)(`${section}:`, manifest.yamlContentByLine));
78
- };
79
- this.handleError = (path, error, manifest) => {
80
- const rootManifestSection = path[0];
81
- const manifestSection = path[path.length - 1];
82
- if (this.isDeprecatedField(manifestSection, error)) {
83
- return this.handleDeprecatedField(manifestSection, error, manifest);
84
- }
85
- if (rootManifestSection === 'modules') {
86
- return this.handleModuleError(path.slice(1), error, manifest);
87
- }
88
- return this.handleGenericError(path, error, manifest);
89
- };
90
14
  const ajv = new ajv_1.default({ allErrors: true, verbose: true, strict: false });
91
15
  (0, ajv_formats_1.default)(ajv);
92
16
  ajv.addVocabulary(['defaultValue', 'fieldDescription', 'fieldTitle', 'shortClassName']);
93
17
  this.validateSchema = ajv.compile(this.schema);
94
18
  }
19
+ processErrorMessage = (error) => {
20
+ if (error.keyword === 'required' && error.schemaPath.includes('oneOf')) {
21
+ return undefined;
22
+ }
23
+ if (error.keyword === 'not') {
24
+ return text_1.errors.schema.notAllowed(error.schema.required);
25
+ }
26
+ if (error.keyword === 'enum') {
27
+ return text_1.errors.schema.enumValues(error.params.allowedValues);
28
+ }
29
+ if (error.keyword === 'oneOf') {
30
+ if (error.params.passingSchemas) {
31
+ const requiredProps = error.params.passingSchemas.map((v) => error.schema[v].required);
32
+ return text_1.errors.schema.oneOf(requiredProps);
33
+ }
34
+ else if (error.parentSchema?.oneOf) {
35
+ const requiredProps = error.parentSchema.oneOf
36
+ .map((v) => v.required)
37
+ .filter((v) => !!v);
38
+ return text_1.errors.schema.oneOf(requiredProps);
39
+ }
40
+ return text_1.errors.schema.oneOf(undefined);
41
+ }
42
+ if (error.keyword === 'additionalProperties' && 'additionalProperty' in error.params) {
43
+ return text_1.errors.schema.additionalProperties(error.params.additionalProperty);
44
+ }
45
+ return error.message;
46
+ };
47
+ handleModuleError = (path, error, manifest) => {
48
+ const hasProperty = path.length > 1;
49
+ const propertyName = path[path.length - 1];
50
+ const errorMessage = this.processErrorMessage(error);
51
+ if (!errorMessage) {
52
+ return undefined;
53
+ }
54
+ if (hasProperty) {
55
+ path.splice(path.length - 1, 0, 'property');
56
+ }
57
+ const data = typeof error.data !== 'string' ? undefined : error.data;
58
+ const searchString = data && hasProperty ? `${propertyName}: ${data}` : path[0];
59
+ return {
60
+ message: text_1.errors.schemaError(data, path, errorMessage),
61
+ reference: text_1.References.SchemaError,
62
+ level: 'error',
63
+ ...(0, utils_1.findPosition)(searchString, manifest.yamlContentByLine)
64
+ };
65
+ };
66
+ handleGenericError = (path, error, manifest) => {
67
+ const hasProperty = path.length > 1;
68
+ const propertyName = path[path.length - 1];
69
+ const errorMessage = this.processErrorMessage(error);
70
+ if (!errorMessage) {
71
+ return undefined;
72
+ }
73
+ if (hasProperty) {
74
+ path.splice(path.length - 1, 0, 'property');
75
+ }
76
+ const data = typeof error.data !== 'string' ? undefined : error.data;
77
+ const searchString = error.data && hasProperty ? `${propertyName}: ${error.data}` : propertyName;
78
+ return {
79
+ message: text_1.errors.schemaError(data, path, errorMessage),
80
+ reference: text_1.References.SchemaError,
81
+ level: 'error',
82
+ ...(0, utils_1.findPosition)(searchString, manifest.yamlContentByLine)
83
+ };
84
+ };
85
+ isDeprecatedField = (section, error) => {
86
+ if (error.keyword === 'additionalProperties') {
87
+ return section === 'app' && error.params.additionalProperty === 'name';
88
+ }
89
+ return false;
90
+ };
95
91
  getDeprecationInfo(section, property) {
96
92
  const deprecationInfo = text_1.errors.deprecationInfo;
97
93
  const deprecationSection = deprecationInfo[section];
@@ -102,8 +98,27 @@ class SchemaValidator {
102
98
  return deprecationSection[property];
103
99
  }
104
100
  }
101
+ handleDeprecatedField = (section, error, manifest) => {
102
+ const property = error.params.additionalProperty;
103
+ return {
104
+ message: text_1.errors.schema.deprecatedValue(section, property, this.getDeprecationInfo(section, property)),
105
+ reference: text_1.References.Deprecated,
106
+ level: 'warning',
107
+ ...(0, utils_1.findPosition)(`${section}:`, manifest.yamlContentByLine)
108
+ };
109
+ };
110
+ handleError = (path, error, manifest) => {
111
+ const rootManifestSection = path[0];
112
+ const manifestSection = path[path.length - 1];
113
+ if (this.isDeprecatedField(manifestSection, error)) {
114
+ return this.handleDeprecatedField(manifestSection, error, manifest);
115
+ }
116
+ if (rootManifestSection === 'modules') {
117
+ return this.handleModuleError(path.slice(1), error, manifest);
118
+ }
119
+ return this.handleGenericError(path, error, manifest);
120
+ };
105
121
  async validate(manifest) {
106
- var _a;
107
122
  if (!manifest || !manifest.yamlContent) {
108
123
  return {
109
124
  success: false,
@@ -111,10 +126,12 @@ class SchemaValidator {
111
126
  };
112
127
  }
113
128
  let success = this.validateSchema(manifest.yamlContent);
114
- const errors = (_a = this.validateSchema.errors) === null || _a === void 0 ? void 0 : _a.map((error) => {
129
+ const errors = this.validateSchema.errors
130
+ ?.map((error) => {
115
131
  const values = error.instancePath.replace(/\/\d+/, '').split('/').slice(1);
116
132
  return this.handleError(values, error, manifest);
117
- }).filter((e) => e !== undefined);
133
+ })
134
+ .filter((e) => e !== undefined);
118
135
  const _isEqual = (e1, e2) => {
119
136
  return (e1.level === e2.level &&
120
137
  e1.reference === e2.reference &&
@@ -123,18 +140,21 @@ class SchemaValidator {
123
140
  e1.message === e2.message);
124
141
  };
125
142
  const dedupedErrors = [];
126
- void (errors === null || errors === void 0 ? void 0 : errors.forEach((e) => {
143
+ void errors?.forEach((e) => {
127
144
  if (!(dedupedErrors.filter((de) => _isEqual(e, de)).length > 0)) {
128
145
  dedupedErrors.push(e);
129
146
  }
130
- }));
147
+ });
131
148
  const warningLevel = dedupedErrors.filter((e) => e.level === 'warning');
132
149
  if (warningLevel.length === dedupedErrors.length) {
133
150
  success = true;
134
151
  }
135
152
  return {
136
153
  success,
137
- manifestObject: Object.assign(Object.assign({}, manifest), { typedContent: success ? manifest.yamlContent : undefined }),
154
+ manifestObject: {
155
+ ...manifest,
156
+ typedContent: success ? manifest.yamlContent : undefined
157
+ },
138
158
  errors: dedupedErrors
139
159
  };
140
160
  }
@@ -11,16 +11,15 @@ const handleRedundantSnapshot = () => {
11
11
  };
12
12
  class SnapshotValidator {
13
13
  async validate(manifest) {
14
- var _a, _b, _c;
15
- if (!(manifest === null || manifest === void 0 ? void 0 : manifest.typedContent)) {
14
+ if (!manifest?.typedContent) {
16
15
  return {
17
16
  success: false,
18
17
  manifestObject: manifest
19
18
  };
20
19
  }
21
20
  const validationErrors = [];
22
- if (((_a = manifest.typedContent.app.runtime) === null || _a === void 0 ? void 0 : _a.snapshots) === true &&
23
- ((_c = (_b = manifest.typedContent.app.runtime) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'sandbox') !== 'sandbox') {
21
+ if (manifest.typedContent.app.runtime?.snapshots === true &&
22
+ (manifest.typedContent.app.runtime?.name ?? 'sandbox') !== 'sandbox') {
24
23
  validationErrors.push(handleRedundantSnapshot());
25
24
  }
26
25
  const warningLevel = validationErrors.filter((e) => e.level === 'warning');