@forge/manifest 7.0.0 → 7.1.0-next.1
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 +13 -0
- package/out/builder/processor-builder.js +2 -1
- package/out/processor/abstract-validation-processor.js +2 -2
- package/out/scopes/index.js +6 -7
- package/out/text/errors.d.ts +1 -0
- package/out/text/errors.d.ts.map +1 -1
- package/out/text/errors.js +2 -1
- package/out/utils/index.d.ts +1 -0
- package/out/utils/index.d.ts.map +1 -1
- package/out/utils/index.js +1 -0
- package/out/utils/manifest-parser.d.ts +15 -0
- package/out/utils/manifest-parser.d.ts.map +1 -0
- package/out/utils/manifest-parser.js +42 -0
- package/out/utils/module-references.js +1 -1
- package/out/validators/app-features-validator.js +8 -4
- package/out/validators/connect-authentication-validator.js +8 -4
- package/out/validators/connect-modules-validator.js +18 -3
- package/out/validators/connect-remote-validator.js +16 -7
- package/out/validators/data-classification-validator.js +8 -5
- package/out/validators/display-conditions-validator.js +8 -7
- package/out/validators/entity-property-validator.js +9 -6
- package/out/validators/jql-function-validator.js +9 -6
- package/out/validators/modules-validator.js +136 -49
- package/out/validators/modules-validators/bitbucket/validateBackendModuleEndpoints.js +16 -8
- package/out/validators/modules-validators/confluence/validateCrossModulePropertyUniqueness.js +6 -2
- package/out/validators/modules-validators/confluence/validateCustomContentHierarchy.js +12 -2
- package/out/validators/modules-validators/confluence/validateKeyboardShortcuts.js +7 -2
- package/out/validators/modules-validators/confluence/validatePropertyUniqueness.js +6 -2
- package/out/validators/modules-validators/confluence/validateSingleProperty.js +6 -1
- package/out/validators/modules-validators/jira/ui-modifications.js +6 -1
- package/out/validators/modules-validators/jira/validate-full-admin-page.js +21 -11
- package/out/validators/modules-validators/jira/validate-subpages-in-module.js +12 -2
- package/out/validators/modules-validators/remote/validate-storage-operation.js +8 -4
- package/out/validators/modules-validators/validateModuleScopes.js +7 -2
- package/out/validators/package-validator.js +1 -2
- package/out/validators/permissions-validator.js +32 -24
- package/out/validators/product-trigger-scopes-validator.js +11 -6
- package/out/validators/providers-validator.js +35 -16
- package/out/validators/resources-validator.js +54 -15
- package/out/validators/schema-validator.js +104 -84
- package/out/validators/snapshot-validator.js +3 -4
- package/out/validators/storage-validator.js +41 -14
- package/out/validators/yaml-validator.d.ts +2 -0
- package/out/validators/yaml-validator.d.ts.map +1 -1
- package/out/validators/yaml-validator.js +10 -6
- package/package.json +3 -2
|
@@ -14,11 +14,8 @@ const remote_1 = require("./modules-validators/remote");
|
|
|
14
14
|
const validateModuleScopes_1 = require("./modules-validators/validateModuleScopes");
|
|
15
15
|
const bitbucket_1 = require("./modules-validators/bitbucket");
|
|
16
16
|
class ModulesValidator {
|
|
17
|
-
|
|
18
|
-
this.functionHandlerRegex = /^([a-zA-Z0-9-_]+)\.([a-zA-Z0-9-_]+)$/;
|
|
19
|
-
}
|
|
17
|
+
functionHandlerRegex = /^([a-zA-Z0-9-_]+)\.([a-zA-Z0-9-_]+)$/;
|
|
20
18
|
async validate(manifest) {
|
|
21
|
-
var _a, _b, _c;
|
|
22
19
|
if (!manifest || !manifest.typedContent || !manifest.filePath) {
|
|
23
20
|
return {
|
|
24
21
|
success: false,
|
|
@@ -31,39 +28,67 @@ class ModulesValidator {
|
|
|
31
28
|
const { typedContent: { modules, remotes, permissions }, yamlContentByLine, filePath } = manifest;
|
|
32
29
|
const { function: _function, endpoint: _endpoint } = modules;
|
|
33
30
|
this.checkUnsupportedModules(manifest.typedContent.modules, validationErrors, yamlContentByLine);
|
|
34
|
-
_function
|
|
31
|
+
_function?.forEach((f) => {
|
|
35
32
|
if (f.key.length > 23) {
|
|
36
|
-
validationErrors.push(
|
|
33
|
+
validationErrors.push({
|
|
34
|
+
message: text_1.errors.modules.function.invalidKeyLength(f.key),
|
|
35
|
+
reference: text_1.References.Modules,
|
|
36
|
+
level: 'error',
|
|
37
|
+
...(0, utils_1.findPosition)(f.key, yamlContentByLine)
|
|
38
|
+
});
|
|
37
39
|
}
|
|
38
40
|
});
|
|
39
41
|
if (Object.keys(modules).filter((moduleKey) => this.isNotFunctionOrEndpoint(moduleKey)).length < 1) {
|
|
40
|
-
validationErrors.push(
|
|
42
|
+
validationErrors.push({
|
|
43
|
+
message: text_1.errors.modules.missingModule(),
|
|
44
|
+
reference: text_1.References.Modules,
|
|
45
|
+
level: 'error',
|
|
46
|
+
...(0, utils_1.findPosition)('app', yamlContentByLine)
|
|
47
|
+
});
|
|
41
48
|
}
|
|
42
49
|
const validModules = Object.keys(modules).filter((moduleKey) => this.isNotFunctionOrEndpoint(moduleKey));
|
|
43
50
|
validModules.forEach((moduleKey) => {
|
|
44
|
-
|
|
45
|
-
(_a = modules[moduleKey]) === null || _a === void 0 ? void 0 : _a.forEach((module) => {
|
|
51
|
+
modules[moduleKey]?.forEach((module) => {
|
|
46
52
|
(0, utils_1.findInvalidFunctionReferences)(module, _function).forEach((functionKey) => {
|
|
47
|
-
validationErrors.push(
|
|
53
|
+
validationErrors.push({
|
|
54
|
+
message: text_1.errors.modules.wrongFunctionReference(moduleKey, functionKey),
|
|
55
|
+
reference: text_1.References.Modules,
|
|
56
|
+
level: 'error',
|
|
57
|
+
...(0, utils_1.findPosition)(moduleKey, yamlContentByLine)
|
|
58
|
+
});
|
|
48
59
|
});
|
|
49
60
|
(0, utils_1.findInvalidEndpointReferences)(module, _endpoint).forEach((endpointKey) => {
|
|
50
|
-
validationErrors.push(
|
|
61
|
+
validationErrors.push({
|
|
62
|
+
message: text_1.errors.modules.wrongEndpointReference(moduleKey, endpointKey),
|
|
63
|
+
reference: text_1.References.Modules,
|
|
64
|
+
level: 'error',
|
|
65
|
+
...(0, utils_1.findPosition)(moduleKey, yamlContentByLine)
|
|
66
|
+
});
|
|
51
67
|
});
|
|
52
68
|
});
|
|
53
69
|
});
|
|
54
|
-
this.endpointValidations(_endpoint, validationErrors, yamlContentByLine, remotes,
|
|
70
|
+
this.endpointValidations(_endpoint, validationErrors, yamlContentByLine, remotes, permissions?.scopes || [], modules);
|
|
55
71
|
const moduleKeys = [];
|
|
56
72
|
Object.keys(modules).forEach((moduleKey) => {
|
|
57
|
-
|
|
58
|
-
(_a = modules[moduleKey]) === null || _a === void 0 ? void 0 : _a.forEach((module) => moduleKeys.push(module.key));
|
|
73
|
+
modules[moduleKey]?.forEach((module) => moduleKeys.push(module.key));
|
|
59
74
|
});
|
|
60
75
|
const duplicateKeys = [...new Set(moduleKeys.filter((item, index) => moduleKeys.indexOf(item) != index))];
|
|
61
76
|
duplicateKeys.forEach((duplicateKey) => {
|
|
62
|
-
validationErrors.push(
|
|
77
|
+
validationErrors.push({
|
|
78
|
+
message: text_1.errors.modules.duplicateKeyFound(duplicateKey),
|
|
79
|
+
reference: text_1.References.Modules,
|
|
80
|
+
level: 'error',
|
|
81
|
+
...(0, utils_1.findPosition)(duplicateKey, yamlContentByLine)
|
|
82
|
+
});
|
|
63
83
|
});
|
|
64
|
-
_function
|
|
84
|
+
_function?.forEach((func) => {
|
|
65
85
|
if (!this.functionHandlerRegex.test(func.handler)) {
|
|
66
|
-
validationErrors.push(
|
|
86
|
+
validationErrors.push({
|
|
87
|
+
message: text_1.errors.modules.function.handler.invalidRegex(func.handler, this.functionHandlerRegex),
|
|
88
|
+
reference: text_1.References.Modules,
|
|
89
|
+
level: 'error',
|
|
90
|
+
...(0, utils_1.findPosition)(func.handler, yamlContentByLine)
|
|
91
|
+
});
|
|
67
92
|
}
|
|
68
93
|
else {
|
|
69
94
|
const matches = this.functionHandlerRegex.exec(func.handler);
|
|
@@ -72,21 +97,41 @@ class ModulesValidator {
|
|
|
72
97
|
return (['tsx', 'jsx', 'ts', 'js'].find((ext) => (0, fs_1.existsSync)((0, path_1.resolve)((0, path_1.dirname)(filePath), 'src', `${fileName}.${ext}`))) !== undefined);
|
|
73
98
|
};
|
|
74
99
|
if (!_checkFileExists(fileName)) {
|
|
75
|
-
validationErrors.push(
|
|
100
|
+
validationErrors.push({
|
|
101
|
+
message: text_1.errors.modules.function.handler.fileNotExists(func.handler, fileName),
|
|
102
|
+
reference: text_1.References.Modules,
|
|
103
|
+
level: 'error',
|
|
104
|
+
...(0, utils_1.findPosition)(func.handler, yamlContentByLine)
|
|
105
|
+
});
|
|
76
106
|
}
|
|
77
107
|
}
|
|
78
108
|
});
|
|
79
|
-
|
|
109
|
+
modules[types_1.AllModuleTypes.JiraWorkflowValidator]?.forEach((module) => {
|
|
80
110
|
if (!module.expression && !module.function) {
|
|
81
|
-
validationErrors.push(
|
|
111
|
+
validationErrors.push({
|
|
112
|
+
message: text_1.errors.modules.jiraWorkflowValidator.missingProperty(module.key),
|
|
113
|
+
reference: text_1.References.Modules,
|
|
114
|
+
level: 'error',
|
|
115
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
116
|
+
});
|
|
82
117
|
}
|
|
83
118
|
if (module.expression && module.function) {
|
|
84
|
-
validationErrors.push(
|
|
119
|
+
validationErrors.push({
|
|
120
|
+
message: text_1.errors.modules.jiraWorkflowValidator.invalidProperty(module.key),
|
|
121
|
+
reference: text_1.References.Modules,
|
|
122
|
+
level: 'error',
|
|
123
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
124
|
+
});
|
|
85
125
|
}
|
|
86
126
|
});
|
|
87
|
-
|
|
127
|
+
modules[types_1.AllModuleTypes.JiraWorkflowCondition]?.forEach((module) => {
|
|
88
128
|
if (!(module.expression && module.expression.trim())) {
|
|
89
|
-
validationErrors.push(
|
|
129
|
+
validationErrors.push({
|
|
130
|
+
message: text_1.errors.modules.jiraWorkflowCondition.missingExpression(module.key),
|
|
131
|
+
reference: text_1.References.Modules,
|
|
132
|
+
level: 'error',
|
|
133
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
134
|
+
});
|
|
90
135
|
}
|
|
91
136
|
});
|
|
92
137
|
validationErrors.push(...(0, ui_modifications_1.validateUiModificationsModule)(modules, yamlContentByLine));
|
|
@@ -94,15 +139,19 @@ class ModulesValidator {
|
|
|
94
139
|
[types_1.AllModuleTypes.JiraProjectPage, types_1.AllModuleTypes.JiraProjectSettingsPage, types_1.AllModuleTypes.JiraGlobalPage].forEach((moduleType) => {
|
|
95
140
|
const moduleArray = modules[moduleType];
|
|
96
141
|
if (moduleArray && moduleArray.length > 1) {
|
|
97
|
-
validationErrors.push(
|
|
142
|
+
validationErrors.push({
|
|
143
|
+
message: text_1.errors.modules.singleEntryOfTheModule(moduleType),
|
|
144
|
+
reference: text_1.References.Modules,
|
|
145
|
+
level: 'error',
|
|
146
|
+
...(0, utils_1.findPosition)(moduleArray[1].key, yamlContentByLine)
|
|
147
|
+
});
|
|
98
148
|
}
|
|
99
149
|
if (moduleArray && moduleArray.length === 1) {
|
|
100
150
|
validationErrors.push(...(0, validate_subpages_in_module_1.validateSubpagesInModule)(modules, moduleType, yamlContentByLine));
|
|
101
151
|
}
|
|
102
152
|
});
|
|
103
153
|
[types_1.AllModuleTypes.JiraCustomField, types_1.AllModuleTypes.JiraCustomFieldType].forEach((moduleType) => {
|
|
104
|
-
|
|
105
|
-
(_a = modules[moduleType]) === null || _a === void 0 ? void 0 : _a.forEach((module) => {
|
|
154
|
+
modules[moduleType]?.forEach((module) => {
|
|
106
155
|
if (!module || module.type !== 'object' || !module.schema)
|
|
107
156
|
return;
|
|
108
157
|
const getAliases = (properties = {}) => Object.values(properties)
|
|
@@ -112,17 +161,27 @@ class ModulesValidator {
|
|
|
112
161
|
const aliases = getAliases(module.schema.properties);
|
|
113
162
|
const duplicates = Array.from(new Set(aliases.filter((item, index) => aliases.indexOf(item) != index)));
|
|
114
163
|
if (duplicates.length) {
|
|
115
|
-
validationErrors.push(
|
|
164
|
+
validationErrors.push({
|
|
165
|
+
message: text_1.errors.modules.customFields.searchAlias(duplicates),
|
|
166
|
+
reference: text_1.References.Modules,
|
|
167
|
+
level: 'error',
|
|
168
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
169
|
+
});
|
|
116
170
|
}
|
|
117
171
|
});
|
|
118
172
|
});
|
|
119
173
|
validationErrors.push(...(0, confluence_1.validateConfluenceModules)(modules, yamlContentByLine));
|
|
120
174
|
validationErrors.push(...(0, bitbucket_1.validateBitbucketModules)(modules, yamlContentByLine));
|
|
121
|
-
|
|
175
|
+
modules?.trigger?.forEach((module) => {
|
|
122
176
|
if (module.filter) {
|
|
123
177
|
const onlyJiraEvents = module.events.every((e) => e.includes('jira'));
|
|
124
178
|
if (!onlyJiraEvents) {
|
|
125
|
-
validationErrors.push(
|
|
179
|
+
validationErrors.push({
|
|
180
|
+
message: text_1.errors.modules.trigger.filteringWorksOnlyWithJiraEvents(),
|
|
181
|
+
reference: text_1.References.Modules,
|
|
182
|
+
level: 'error',
|
|
183
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
184
|
+
});
|
|
126
185
|
}
|
|
127
186
|
}
|
|
128
187
|
});
|
|
@@ -142,12 +201,16 @@ class ModulesValidator {
|
|
|
142
201
|
Object.keys(modules)
|
|
143
202
|
.filter((key) => !types_1.SUPPORTED_MODULES.map((key) => (0, utils_1.cleanKey)(key)).includes(key))
|
|
144
203
|
.forEach((invalidKey) => {
|
|
145
|
-
validationErrors.push(
|
|
204
|
+
validationErrors.push({
|
|
205
|
+
message: text_1.errors.modules.invalidModule(invalidKey),
|
|
206
|
+
reference: text_1.References.Modules,
|
|
207
|
+
level: 'error',
|
|
208
|
+
...(0, utils_1.findPosition)(invalidKey, yamlContentByLine)
|
|
209
|
+
});
|
|
146
210
|
});
|
|
147
211
|
}
|
|
148
212
|
connectModuleValidation(manifest, validationErrors) {
|
|
149
|
-
|
|
150
|
-
if (!((_a = manifest.typedContent) === null || _a === void 0 ? void 0 : _a.modules) && !((_b = manifest.typedContent) === null || _b === void 0 ? void 0 : _b.connectModules)) {
|
|
213
|
+
if (!manifest.typedContent?.modules && !manifest.typedContent?.connectModules) {
|
|
151
214
|
validationErrors.push({
|
|
152
215
|
message: text_1.errors.schemaError(undefined, [], text_1.errors.schema.oneOf([['modules'], ['connectModules']])),
|
|
153
216
|
reference: text_1.References.SchemaError,
|
|
@@ -158,39 +221,63 @@ class ModulesValidator {
|
|
|
158
221
|
}
|
|
159
222
|
}
|
|
160
223
|
endpointValidations(_endpoint, validationErrors, yamlContentByLine, remotes, scopes, modules) {
|
|
161
|
-
var _a;
|
|
162
224
|
const SYSTEM_TOKEN_SCOPE = 'read:app-system-token';
|
|
163
225
|
const USER_TOKEN_SCOPE = 'read:app-user-token';
|
|
164
226
|
const _checkRemoteExists = (remoteKey) => {
|
|
165
|
-
return
|
|
227
|
+
return remotes?.find((remote) => remote.key === remoteKey) !== undefined;
|
|
166
228
|
};
|
|
167
|
-
const eventModulesWithEndpoint =
|
|
229
|
+
const eventModulesWithEndpoint = modules?.trigger?.filter((trigger) => trigger.endpoint != null) || [];
|
|
168
230
|
eventModulesWithEndpoint.forEach((event) => {
|
|
169
|
-
|
|
170
|
-
const endpointModule = _endpoint === null || _endpoint === void 0 ? void 0 : _endpoint.find((remoteEndpoint) => remoteEndpoint.key === event.endpoint);
|
|
231
|
+
const endpointModule = _endpoint?.find((remoteEndpoint) => remoteEndpoint.key === event.endpoint);
|
|
171
232
|
if (endpointModule) {
|
|
172
|
-
if (
|
|
173
|
-
validationErrors.push(
|
|
233
|
+
if (endpointModule.auth?.appUserToken?.enabled) {
|
|
234
|
+
validationErrors.push({
|
|
235
|
+
message: text_1.errors.modules.trigger.endpointOnlySupportSystemToken(event.key, endpointModule.key),
|
|
236
|
+
reference: text_1.References.Modules,
|
|
237
|
+
level: 'error',
|
|
238
|
+
...(0, utils_1.findPosition)(endpointModule.key, yamlContentByLine)
|
|
239
|
+
});
|
|
174
240
|
}
|
|
175
241
|
if (endpointModule.route === null || endpointModule.route === undefined) {
|
|
176
|
-
validationErrors.push(
|
|
242
|
+
validationErrors.push({
|
|
243
|
+
message: text_1.errors.modules.trigger.endpointNeedsRoute(event.key, endpointModule.key),
|
|
244
|
+
reference: text_1.References.Modules,
|
|
245
|
+
level: 'error',
|
|
246
|
+
...(0, utils_1.findPosition)(endpointModule.key, yamlContentByLine)
|
|
247
|
+
});
|
|
177
248
|
}
|
|
178
249
|
}
|
|
179
250
|
});
|
|
180
|
-
_endpoint
|
|
181
|
-
var _a, _b, _c, _d;
|
|
251
|
+
_endpoint?.forEach((endpoint) => {
|
|
182
252
|
if (!_checkRemoteExists(endpoint.remote)) {
|
|
183
|
-
validationErrors.push(
|
|
253
|
+
validationErrors.push({
|
|
254
|
+
message: text_1.errors.modules.endpoint.remote.notExists(endpoint.remote),
|
|
255
|
+
reference: text_1.References.Modules,
|
|
256
|
+
level: 'error',
|
|
257
|
+
...(0, utils_1.findPosition)(endpoint.remote, yamlContentByLine)
|
|
258
|
+
});
|
|
184
259
|
}
|
|
185
|
-
if (
|
|
186
|
-
validationErrors.push(
|
|
260
|
+
if (endpoint.auth?.appUserToken?.enabled && !scopes.includes(USER_TOKEN_SCOPE)) {
|
|
261
|
+
validationErrors.push({
|
|
262
|
+
message: text_1.errors.permissions.missingEndpointPermissionFromScope(USER_TOKEN_SCOPE, endpoint.key),
|
|
263
|
+
reference: text_1.References.MissingScopes,
|
|
264
|
+
level: 'error',
|
|
265
|
+
metadata: {
|
|
187
266
|
missingPermission: USER_TOKEN_SCOPE
|
|
188
|
-
}
|
|
267
|
+
},
|
|
268
|
+
...(0, utils_1.findPosition)('scopes', yamlContentByLine)
|
|
269
|
+
});
|
|
189
270
|
}
|
|
190
|
-
if (
|
|
191
|
-
validationErrors.push(
|
|
271
|
+
if (endpoint.auth?.appSystemToken?.enabled && !scopes.includes(SYSTEM_TOKEN_SCOPE)) {
|
|
272
|
+
validationErrors.push({
|
|
273
|
+
message: text_1.errors.permissions.missingEndpointPermissionFromScope(SYSTEM_TOKEN_SCOPE, endpoint.key),
|
|
274
|
+
reference: text_1.References.MissingScopes,
|
|
275
|
+
level: 'error',
|
|
276
|
+
metadata: {
|
|
192
277
|
missingPermission: SYSTEM_TOKEN_SCOPE
|
|
193
|
-
}
|
|
278
|
+
},
|
|
279
|
+
...(0, utils_1.findPosition)('scopes', yamlContentByLine)
|
|
280
|
+
});
|
|
194
281
|
}
|
|
195
282
|
});
|
|
196
283
|
}
|
|
@@ -5,19 +5,27 @@ const text_1 = require("../../../text");
|
|
|
5
5
|
const types_1 = require("../../../types");
|
|
6
6
|
const utils_1 = require("../../../utils");
|
|
7
7
|
const validateBackendModuleEndpoints = (modules, yamlContentByLine) => {
|
|
8
|
-
|
|
9
|
-
const endpoints = (_a = modules.endpoint) !== null && _a !== void 0 ? _a : [];
|
|
8
|
+
const endpoints = modules.endpoint ?? [];
|
|
10
9
|
const validationErrors = [];
|
|
11
|
-
const backendModulesWithEndpoint =
|
|
10
|
+
const backendModulesWithEndpoint = modules[types_1.AllModuleTypes.BitbucketMergeCheck]?.filter((module) => module.endpoint != null) || [];
|
|
12
11
|
backendModulesWithEndpoint.forEach((module) => {
|
|
13
|
-
|
|
14
|
-
const endpointModule = endpoints === null || endpoints === void 0 ? void 0 : endpoints.find((remoteEndpoint) => remoteEndpoint.key === module.endpoint);
|
|
12
|
+
const endpointModule = endpoints?.find((remoteEndpoint) => remoteEndpoint.key === module.endpoint);
|
|
15
13
|
if (endpointModule) {
|
|
16
|
-
if (
|
|
17
|
-
validationErrors.push(
|
|
14
|
+
if (endpointModule.auth?.appUserToken?.enabled) {
|
|
15
|
+
validationErrors.push({
|
|
16
|
+
message: text_1.errors.modules.bitbucket.endpointOnlySupportSystemToken(module.key, endpointModule.key),
|
|
17
|
+
reference: text_1.References.Modules,
|
|
18
|
+
level: 'error',
|
|
19
|
+
...(0, utils_1.findPosition)(endpointModule.key, yamlContentByLine)
|
|
20
|
+
});
|
|
18
21
|
}
|
|
19
22
|
if (!endpointModule.route) {
|
|
20
|
-
validationErrors.push(
|
|
23
|
+
validationErrors.push({
|
|
24
|
+
message: text_1.errors.modules.bitbucket.endpointNeedsRoute(module.key, endpointModule.key),
|
|
25
|
+
reference: text_1.References.Modules,
|
|
26
|
+
level: 'error',
|
|
27
|
+
...(0, utils_1.findPosition)(endpointModule.key, yamlContentByLine)
|
|
28
|
+
});
|
|
21
29
|
}
|
|
22
30
|
}
|
|
23
31
|
});
|
package/out/validators/modules-validators/confluence/validateCrossModulePropertyUniqueness.js
CHANGED
|
@@ -6,14 +6,18 @@ const get_1 = tslib_1.__importDefault(require("lodash/get"));
|
|
|
6
6
|
const text_1 = require("../../../text");
|
|
7
7
|
const utils_1 = require("../../../utils");
|
|
8
8
|
const validateCrossModulePropertyUniqueness = (allModules, property, yamlContentByLine) => {
|
|
9
|
-
var _a;
|
|
10
9
|
const validationErrors = [];
|
|
11
10
|
const modules = (0, utils_1.getAllModules)(allModules) || [];
|
|
12
11
|
const allPropertyValues = modules.map((module) => (0, get_1.default)(module, property)).filter((propertyValue) => propertyValue);
|
|
13
12
|
const duplicatePropertyValues = allPropertyValues.filter((propertyValue, index, all) => all.indexOf(propertyValue) !== index);
|
|
14
13
|
if (duplicatePropertyValues.length > 0) {
|
|
15
14
|
const allModulesWithDuplicatedPropertyValues = modules.filter((module) => (0, get_1.default)(module, property) === duplicatePropertyValues[0]);
|
|
16
|
-
validationErrors.push(
|
|
15
|
+
validationErrors.push({
|
|
16
|
+
message: text_1.errors.modules.confluence.crossModulePropertyUniqueness(property, duplicatePropertyValues),
|
|
17
|
+
reference: text_1.References.Modules,
|
|
18
|
+
level: 'error',
|
|
19
|
+
...(0, utils_1.findPosition)(allModulesWithDuplicatedPropertyValues?.[0]?.key, yamlContentByLine)
|
|
20
|
+
});
|
|
17
21
|
}
|
|
18
22
|
return validationErrors;
|
|
19
23
|
};
|
|
@@ -28,12 +28,22 @@ const validateCustomContentHierarchy = (allModules, moduleType, yamlContentByLin
|
|
|
28
28
|
const referredModuleName = value.substring(INNER_TYPE_PREFIX.length);
|
|
29
29
|
const referredModule = modules.find((m) => m.key === referredModuleName);
|
|
30
30
|
if (!referredModule) {
|
|
31
|
-
validationErrors.push(
|
|
31
|
+
validationErrors.push({
|
|
32
|
+
message: text_1.errors.modules.confluence.validateCustomContentHierarchyUnknown(propName, module.key, referredModuleName),
|
|
33
|
+
reference: text_1.References.Modules,
|
|
34
|
+
level: 'error',
|
|
35
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
36
|
+
});
|
|
32
37
|
}
|
|
33
38
|
else {
|
|
34
39
|
const referredModuleDependentPropValues = referredModule[dependentPropName] || [];
|
|
35
40
|
if (!referredModuleDependentPropValues.includes(`${INNER_TYPE_PREFIX}${module.key}`)) {
|
|
36
|
-
validationErrors.push(
|
|
41
|
+
validationErrors.push({
|
|
42
|
+
message: dependentReferenceMissingMessage(module.key, referredModule.key),
|
|
43
|
+
reference: text_1.References.Modules,
|
|
44
|
+
level: 'error',
|
|
45
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
46
|
+
});
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
49
|
});
|
|
@@ -105,9 +105,14 @@ const validateShortcut = (moduleKey, accelerator) => {
|
|
|
105
105
|
const validateKeyboardShortcuts = (allModules, yamlContentByLine) => {
|
|
106
106
|
const validationErrors = [];
|
|
107
107
|
const modules = (0, utils_1.getAllModules)(allModules) || [];
|
|
108
|
-
const modulesWithKeyboardShortcut = modules.filter((module) =>
|
|
108
|
+
const modulesWithKeyboardShortcut = modules.filter((module) => module?.keyboardShortcut?.accelerator);
|
|
109
109
|
if (modulesWithKeyboardShortcut.length > 0) {
|
|
110
|
-
modulesWithKeyboardShortcut.forEach((m) => validationErrors.push(...validateShortcut(m.key, m.keyboardShortcut.accelerator).map((e) => (
|
|
110
|
+
modulesWithKeyboardShortcut.forEach((m) => validationErrors.push(...validateShortcut(m.key, m.keyboardShortcut.accelerator).map((e) => ({
|
|
111
|
+
message: e.message,
|
|
112
|
+
reference: text_1.References.Modules,
|
|
113
|
+
level: 'error',
|
|
114
|
+
...(0, utils_1.findPosition)(e.moduleKey, yamlContentByLine)
|
|
115
|
+
}))));
|
|
111
116
|
}
|
|
112
117
|
return validationErrors;
|
|
113
118
|
};
|
|
@@ -4,14 +4,18 @@ exports.validatePropertyUniqueness = void 0;
|
|
|
4
4
|
const text_1 = require("../../../text");
|
|
5
5
|
const utils_1 = require("../../../utils");
|
|
6
6
|
const validatePropertyUniqueness = (allModules, moduleType, property, yamlContentByLine) => {
|
|
7
|
-
var _a;
|
|
8
7
|
const validationErrors = [];
|
|
9
8
|
const modules = allModules[moduleType] || [];
|
|
10
9
|
const allPropertyValues = modules.map((module) => module[property]).filter((property) => property);
|
|
11
10
|
const duplicatePropertyValues = allPropertyValues.filter((property, index, all) => all.indexOf(property) !== index);
|
|
12
11
|
if (duplicatePropertyValues.length > 0) {
|
|
13
12
|
const allModulesWithDuplicatedPropertyValues = modules.filter((module) => module[property] === duplicatePropertyValues[0]);
|
|
14
|
-
validationErrors.push(
|
|
13
|
+
validationErrors.push({
|
|
14
|
+
message: text_1.errors.modules.confluence.propertyUniqueness(property, moduleType, duplicatePropertyValues),
|
|
15
|
+
reference: text_1.References.Modules,
|
|
16
|
+
level: 'error',
|
|
17
|
+
...(0, utils_1.findPosition)(allModulesWithDuplicatedPropertyValues?.[0]?.key, yamlContentByLine)
|
|
18
|
+
});
|
|
15
19
|
}
|
|
16
20
|
return validationErrors;
|
|
17
21
|
};
|
|
@@ -9,7 +9,12 @@ const validateSingleProperty = (allModules, moduleType, property, yamlContentByL
|
|
|
9
9
|
const modulesWithProperty = modules.filter((module) => module[property]);
|
|
10
10
|
if (modulesWithProperty.length > 1) {
|
|
11
11
|
const moduleKeys = modulesWithProperty.map((module) => module.key);
|
|
12
|
-
validationErrors.push(
|
|
12
|
+
validationErrors.push({
|
|
13
|
+
message: text_1.errors.modules.confluence.multipleProperty(property, moduleType, moduleKeys),
|
|
14
|
+
reference: text_1.References.Modules,
|
|
15
|
+
level: 'error',
|
|
16
|
+
...(0, utils_1.findPosition)(moduleKeys[moduleKeys.length - 1], yamlContentByLine)
|
|
17
|
+
});
|
|
13
18
|
}
|
|
14
19
|
return validationErrors;
|
|
15
20
|
};
|
|
@@ -9,7 +9,12 @@ function validateUiModificationsModule(modules, yamlContentByLine) {
|
|
|
9
9
|
const moduleType = types_1.AllModuleTypes.JiraUiModifications;
|
|
10
10
|
const moduleArray = modules[moduleType];
|
|
11
11
|
if (moduleArray && moduleArray.length > 1) {
|
|
12
|
-
validationErrors.push(
|
|
12
|
+
validationErrors.push({
|
|
13
|
+
message: text_1.errors.modules.singleEntryOfTheModule(moduleType),
|
|
14
|
+
reference: text_1.References.Modules,
|
|
15
|
+
level: 'error',
|
|
16
|
+
...(0, utils_1.findPosition)(moduleArray[1].key, yamlContentByLine)
|
|
17
|
+
});
|
|
13
18
|
}
|
|
14
19
|
return validationErrors;
|
|
15
20
|
}
|
|
@@ -8,18 +8,28 @@ const validate_subpages_in_module_1 = require("./validate-subpages-in-module");
|
|
|
8
8
|
const jiraAdminPageType = types_1.AllModuleTypes.JiraAdminPage;
|
|
9
9
|
const validateSeparateAdminPageModule = (pageType, modules, currentModule, multiplePagesError, yamlContentByLine) => {
|
|
10
10
|
const validationErrors = [];
|
|
11
|
-
if (
|
|
12
|
-
validationErrors.push(
|
|
11
|
+
if (currentModule?.length > 1) {
|
|
12
|
+
validationErrors.push({
|
|
13
|
+
message: multiplePagesError,
|
|
14
|
+
reference: text_1.References.Modules,
|
|
15
|
+
level: 'error',
|
|
16
|
+
...(0, utils_1.findPosition)(currentModule[1].key, yamlContentByLine)
|
|
17
|
+
});
|
|
13
18
|
}
|
|
14
|
-
if (
|
|
19
|
+
if (currentModule?.length === 1) {
|
|
15
20
|
if (pageType === 'admin') {
|
|
16
|
-
const adminModules =
|
|
21
|
+
const adminModules = { ...modules, [jiraAdminPageType]: currentModule };
|
|
17
22
|
validationErrors.push(...(0, validate_subpages_in_module_1.validateSubpagesInModule)(adminModules, jiraAdminPageType, yamlContentByLine));
|
|
18
23
|
}
|
|
19
24
|
if (['get-started', 'config'].includes(pageType)) {
|
|
20
25
|
const { pages, sections, key } = currentModule[0];
|
|
21
26
|
if (pages || sections)
|
|
22
|
-
validationErrors.push(
|
|
27
|
+
validationErrors.push({
|
|
28
|
+
message: text_1.errors.modules.subPages.invalidPagesAndSectionsForConfigurePages(jiraAdminPageType),
|
|
29
|
+
reference: text_1.References.Modules,
|
|
30
|
+
level: 'error',
|
|
31
|
+
...(0, utils_1.findPosition)(key, yamlContentByLine)
|
|
32
|
+
});
|
|
23
33
|
}
|
|
24
34
|
}
|
|
25
35
|
return validationErrors;
|
|
@@ -27,16 +37,16 @@ const validateSeparateAdminPageModule = (pageType, modules, currentModule, multi
|
|
|
27
37
|
const validateFullAdminPage = (modules, yamlContentByLine) => {
|
|
28
38
|
const validationErrors = [];
|
|
29
39
|
const moduleArray = modules[jiraAdminPageType];
|
|
30
|
-
const adminPageModules = moduleArray
|
|
31
|
-
const getStartedModules = moduleArray
|
|
32
|
-
const configModules = moduleArray
|
|
33
|
-
if (adminPageModules
|
|
40
|
+
const adminPageModules = moduleArray?.filter((module) => !module?.useAsGetStarted && !module?.useAsConfig);
|
|
41
|
+
const getStartedModules = moduleArray?.filter((module) => module?.useAsGetStarted);
|
|
42
|
+
const configModules = moduleArray?.filter((module) => module?.useAsConfig);
|
|
43
|
+
if (adminPageModules?.length) {
|
|
34
44
|
validationErrors.push(...validateSeparateAdminPageModule('admin', modules, adminPageModules, text_1.errors.modules.singleEntryOfModuleWithoutConfigureAndStartedParams(jiraAdminPageType), yamlContentByLine));
|
|
35
45
|
}
|
|
36
|
-
if (getStartedModules
|
|
46
|
+
if (getStartedModules?.length) {
|
|
37
47
|
validationErrors.push(...validateSeparateAdminPageModule('get-started', modules, getStartedModules, text_1.errors.modules.singleEntryOfModuleWithGetStartedParam(jiraAdminPageType), yamlContentByLine));
|
|
38
48
|
}
|
|
39
|
-
if (configModules
|
|
49
|
+
if (configModules?.length) {
|
|
40
50
|
validationErrors.push(...validateSeparateAdminPageModule('config', modules, configModules, text_1.errors.modules.singleEntryOfModuleWithConfigureParam(jiraAdminPageType), yamlContentByLine));
|
|
41
51
|
}
|
|
42
52
|
return validationErrors;
|
|
@@ -8,10 +8,20 @@ const validateSubpagesInModule = (modules, moduleType, yamlContentByLine) => {
|
|
|
8
8
|
const moduleArray = modules[moduleType];
|
|
9
9
|
const module = moduleArray[0];
|
|
10
10
|
if (module && (module.pages || module.sections) && module.function) {
|
|
11
|
-
validationErrors.push(
|
|
11
|
+
validationErrors.push({
|
|
12
|
+
message: text_1.errors.modules.subPages.subPagesWithUIKit(module.key),
|
|
13
|
+
reference: text_1.References.Modules,
|
|
14
|
+
level: 'error',
|
|
15
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
16
|
+
});
|
|
12
17
|
}
|
|
13
18
|
if (module && module.pages && module.sections) {
|
|
14
|
-
validationErrors.push(
|
|
19
|
+
validationErrors.push({
|
|
20
|
+
message: text_1.errors.modules.subPages.invalidPagesAndSections(module.key),
|
|
21
|
+
reference: text_1.References.Modules,
|
|
22
|
+
level: 'error',
|
|
23
|
+
...(0, utils_1.findPosition)(module.key, yamlContentByLine)
|
|
24
|
+
});
|
|
15
25
|
}
|
|
16
26
|
return validationErrors;
|
|
17
27
|
};
|
|
@@ -6,12 +6,16 @@ const types_1 = require("../../../types");
|
|
|
6
6
|
const text_1 = require("../../../text");
|
|
7
7
|
const utils_1 = require("../../../utils");
|
|
8
8
|
const validateStorageOperation = (allModules, yamlContentByLine) => {
|
|
9
|
-
var _a, _b;
|
|
10
9
|
const validationErrors = [];
|
|
11
10
|
const remotes = allModules[(0, module_key_cleaner_1.cleanKey)(types_1.AllModuleTypes.CoreRemote)];
|
|
12
|
-
for (const remote of remotes
|
|
13
|
-
if (
|
|
14
|
-
validationErrors.push(
|
|
11
|
+
for (const remote of remotes ?? []) {
|
|
12
|
+
if (remote.operations?.includes('storage') && !remote.storage?.inScopeEUD) {
|
|
13
|
+
validationErrors.push({
|
|
14
|
+
message: text_1.errors.modules.remote.missingModuleRemoteStorageInScopeEUD(remote.key),
|
|
15
|
+
reference: text_1.References.Modules,
|
|
16
|
+
level: 'error',
|
|
17
|
+
...(0, utils_1.findPosition)(remote.key, yamlContentByLine)
|
|
18
|
+
});
|
|
15
19
|
}
|
|
16
20
|
}
|
|
17
21
|
return validationErrors;
|
|
@@ -6,13 +6,18 @@ const utils_1 = require("../../utils");
|
|
|
6
6
|
const module_to_scope_mapping_1 = require("../../mapping/module-to-scope-mapping");
|
|
7
7
|
const validateModuleScopes = (modules, yamlContentByLine, permissions) => {
|
|
8
8
|
const validationErrors = [];
|
|
9
|
-
const scopes =
|
|
9
|
+
const scopes = permissions?.scopes || [];
|
|
10
10
|
module_to_scope_mapping_1.MODULE_TO_SCOPES_MAPPING.forEach((requiredScopes, moduleType) => {
|
|
11
11
|
const modulesToValidate = modules[moduleType];
|
|
12
12
|
if (modulesToValidate) {
|
|
13
13
|
if (!requiredScopes.every((s) => scopes.includes(s))) {
|
|
14
14
|
modulesToValidate.forEach((m) => {
|
|
15
|
-
validationErrors.push(
|
|
15
|
+
validationErrors.push({
|
|
16
|
+
message: text_1.errors.modules.moduleScopesValidator.missingScopes(moduleType, m.key, requiredScopes),
|
|
17
|
+
reference: text_1.References.MissingScopes,
|
|
18
|
+
level: 'error',
|
|
19
|
+
...(0, utils_1.findPosition)(m.key, yamlContentByLine)
|
|
20
|
+
});
|
|
16
21
|
});
|
|
17
22
|
}
|
|
18
23
|
}
|
|
@@ -10,8 +10,7 @@ class PackageValidator {
|
|
|
10
10
|
return (await (0, glob_1.glob)(pattern)).some((file) => fs_1.default.lstatSync(file).isFile());
|
|
11
11
|
}
|
|
12
12
|
async validate(manifest) {
|
|
13
|
-
|
|
14
|
-
const extraFiles = (_d = (_c = (_b = (_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a.app) === null || _b === void 0 ? void 0 : _b.package) === null || _c === void 0 ? void 0 : _c.extraFiles) !== null && _d !== void 0 ? _d : [];
|
|
13
|
+
const extraFiles = manifest?.typedContent?.app?.package?.extraFiles ?? [];
|
|
15
14
|
const validationErrors = [];
|
|
16
15
|
for (const glob of extraFiles) {
|
|
17
16
|
if (!(await this.fileExistsForGlob(glob))) {
|