@forge/manifest 7.3.0-next.4 → 7.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 +6 -0
- package/out/builder/processor-builder.js +2 -1
- package/out/processor/abstract-validation-processor.js +2 -2
- package/out/schema/manifest-schema.json +19 -0
- package/out/schema/manifest.d.ts +8 -0
- 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 +16 -0
- package/out/utils/manifest-parser.d.ts.map +1 -0
- package/out/utils/manifest-parser.js +52 -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 +155 -57
- 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 +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,8 @@ const processor_1 = require("../processor");
|
|
|
6
6
|
const deprecated_csp_method_validation_processor_1 = require("../processor/deprecated-csp-method-validation-processor");
|
|
7
7
|
const remote_compute_validation_processor_1 = require("../processor/remote-compute-validation-processor");
|
|
8
8
|
class ProcessorBuilder {
|
|
9
|
+
static cache = new Map();
|
|
10
|
+
validationType;
|
|
9
11
|
constructor() {
|
|
10
12
|
this.validationType = types_1.ValidationTypes.FULL;
|
|
11
13
|
}
|
|
@@ -43,4 +45,3 @@ class ProcessorBuilder {
|
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
exports.ProcessorBuilder = ProcessorBuilder;
|
|
46
|
-
ProcessorBuilder.cache = new Map();
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AbstractValidationProcessor = void 0;
|
|
4
4
|
class AbstractValidationProcessor {
|
|
5
|
+
validators;
|
|
5
6
|
constructor(validators) {
|
|
6
7
|
this.validators = validators;
|
|
7
8
|
}
|
|
8
9
|
async process(manifest) {
|
|
9
|
-
var _a;
|
|
10
10
|
let results = {
|
|
11
11
|
success: true
|
|
12
12
|
};
|
|
13
13
|
for (const validator of this.validators) {
|
|
14
|
-
const stepResults = await validator.validate(
|
|
14
|
+
const stepResults = await validator.validate(results.manifestObject ?? manifest);
|
|
15
15
|
results = {
|
|
16
16
|
success: results.success && stepResults.success,
|
|
17
17
|
manifestObject: stepResults.manifestObject || results.manifestObject,
|
|
@@ -17799,6 +17799,21 @@
|
|
|
17799
17799
|
}
|
|
17800
17800
|
}
|
|
17801
17801
|
},
|
|
17802
|
+
"EnvironmentSchema": {
|
|
17803
|
+
"type": "object",
|
|
17804
|
+
"additionalProperties": false,
|
|
17805
|
+
"properties": {
|
|
17806
|
+
"variables": {
|
|
17807
|
+
"type": "array",
|
|
17808
|
+
"title": "variables",
|
|
17809
|
+
"description": "Manifest environment variables",
|
|
17810
|
+
"items": {
|
|
17811
|
+
"type": "string",
|
|
17812
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
|
|
17813
|
+
}
|
|
17814
|
+
}
|
|
17815
|
+
}
|
|
17816
|
+
},
|
|
17802
17817
|
"OAuth2ScopeName": {
|
|
17803
17818
|
"type": "string",
|
|
17804
17819
|
"pattern": "^[^\\s]+$"
|
|
@@ -20133,6 +20148,10 @@
|
|
|
20133
20148
|
"providers": {
|
|
20134
20149
|
"$ref": "#/definitions/ProvidersSchema",
|
|
20135
20150
|
"title": "providers"
|
|
20151
|
+
},
|
|
20152
|
+
"environment": {
|
|
20153
|
+
"$ref": "#/definitions/EnvironmentSchema",
|
|
20154
|
+
"title": "environment"
|
|
20136
20155
|
}
|
|
20137
20156
|
},
|
|
20138
20157
|
"required": [
|
package/out/schema/manifest.d.ts
CHANGED
|
@@ -409,6 +409,10 @@ export type OAuth2ScopeName = string;
|
|
|
409
409
|
* External authentication providers
|
|
410
410
|
*/
|
|
411
411
|
export type Auth = (AuthProviderCustom | AuthProviderPredefined)[];
|
|
412
|
+
/**
|
|
413
|
+
* Manifest environment variables
|
|
414
|
+
*/
|
|
415
|
+
export type Variables = string[];
|
|
412
416
|
|
|
413
417
|
export interface ManifestSchema {
|
|
414
418
|
app: App;
|
|
@@ -418,6 +422,7 @@ export interface ManifestSchema {
|
|
|
418
422
|
resources?: Resources;
|
|
419
423
|
remotes?: Remotes;
|
|
420
424
|
providers?: Providers;
|
|
425
|
+
environment?: Environment;
|
|
421
426
|
}
|
|
422
427
|
export interface App {
|
|
423
428
|
description?: Description;
|
|
@@ -56834,3 +56839,6 @@ export interface AuthProviderPredefined {
|
|
|
56834
56839
|
scopes?: OAuth2ScopeName[];
|
|
56835
56840
|
remotes: ModuleKeySchema[];
|
|
56836
56841
|
}
|
|
56842
|
+
export interface Environment {
|
|
56843
|
+
variables?: Variables;
|
|
56844
|
+
}
|
package/out/scopes/index.js
CHANGED
|
@@ -4,20 +4,19 @@ exports.getScopesWithInteractiveConsent = exports.getMissingScopes = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const shipyard_scopes_with_interactive_consent_json_1 = tslib_1.__importDefault(require("./shipyard-scopes-with-interactive-consent.json"));
|
|
6
6
|
async function getMissingScopes(existing, required) {
|
|
7
|
-
|
|
8
|
-
if (!(existing === null || existing === void 0 ? void 0 : existing.length)) {
|
|
7
|
+
if (!existing?.length) {
|
|
9
8
|
return required.current;
|
|
10
9
|
}
|
|
11
10
|
if (required.current.length === 0)
|
|
12
11
|
return [];
|
|
13
|
-
const missingCurrent = required.current.filter((scope) => !
|
|
12
|
+
const missingCurrent = required.current.filter((scope) => !existing?.includes(scope));
|
|
14
13
|
if (missingCurrent.length === 0)
|
|
15
14
|
return [];
|
|
16
|
-
const missingBeta =
|
|
17
|
-
if (required.beta &&
|
|
15
|
+
const missingBeta = required.beta?.filter((scope) => !existing?.includes(scope));
|
|
16
|
+
if (required.beta && missingBeta?.length === 0)
|
|
18
17
|
return [];
|
|
19
|
-
const missingDeprecated =
|
|
20
|
-
if (required.deprecated &&
|
|
18
|
+
const missingDeprecated = required.deprecated?.filter((scope) => !existing?.includes(scope));
|
|
19
|
+
if (required.deprecated && missingDeprecated?.length === 0)
|
|
21
20
|
return [];
|
|
22
21
|
return missingCurrent;
|
|
23
22
|
}
|
package/out/text/errors.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare const errors: {
|
|
|
9
9
|
deprecatedValue: (section: string, field: string, additionalInfo?: string) => string;
|
|
10
10
|
additionalProperties: (additionalProperty: string) => string;
|
|
11
11
|
notAllowed: (props: string[] | undefined) => string;
|
|
12
|
+
missingEnvironmentVariable: (variable: string) => string;
|
|
12
13
|
};
|
|
13
14
|
permissions: {
|
|
14
15
|
invalidPermission: (element: string, value: string) => string;
|
package/out/text/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/text/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,eAAO,MAAM,MAAM;8BACS,MAAM,KAAG,MAAM;2BACpB,MAAM;yBAEN,MAAM,GAAG,SAAS,QAAQ,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,KAAG,MAAM;;uBAO3E,MAAM,EAAE,EAAE,GAAG,SAAS,KAAG,MAAM;4BAI1B,MAAM,EAAE,KAAG,MAAM;mCACV,MAAM,SAAS,MAAM,mBAAmB,MAAM,KAAG,MAAM;mDAIvC,MAAM,KAAG,MAAM;4BAEtC,MAAM,EAAE,GAAG,SAAS,KAAG,MAAM;;;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/text/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,eAAO,MAAM,MAAM;8BACS,MAAM,KAAG,MAAM;2BACpB,MAAM;yBAEN,MAAM,GAAG,SAAS,QAAQ,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,KAAG,MAAM;;uBAO3E,MAAM,EAAE,EAAE,GAAG,SAAS,KAAG,MAAM;4BAI1B,MAAM,EAAE,KAAG,MAAM;mCACV,MAAM,SAAS,MAAM,mBAAmB,MAAM,KAAG,MAAM;mDAIvC,MAAM,KAAG,MAAM;4BAEtC,MAAM,EAAE,GAAG,SAAS,KAAG,MAAM;+CAIV,MAAM;;;qCAGhB,MAAM,SAAS,MAAM,KAAG,MAAM;4CAEvB,MAAM,SAAS,MAAM,KAAG,MAAM;oDAEtB,MAAM,OAAO,MAAM,KAAG,MAAM;kDAE9B,MAAM,OAAO,MAAM,KAAG,MAAM;wCAEtC,MAAM,SAAS,MAAM,EAAE,KAAG,MAAM;;;uCAMjC,MAAM,KAAG,MAAM;oCACpB,MAAM;iCAEP,MAAM,KAAG,MAAM;4CACJ,MAAM,KAAG,MAAM;;;gCAG3B,MAAM,KAAG,MAAM;6BACpB,MAAM;+BACJ,MAAM;iCACF,MAAM,KAAG,MAAM;yCACP,MAAM,eAAe,MAAM,KAAG,MAAM;yCAEpC,MAAM,eAAe,MAAM,KAAG,MAAM;yCAEpC,MAAM,eAAe,MAAM,KAAG,MAAM;oCAEzC,MAAM;6CACG,MAAM,KAAG,MAAM;0EAEc,MAAM,KAAG,MAAM;4DAE7B,MAAM,KAAG,MAAM;6DAEd,MAAM,KAAG,MAAM;;yCAGrC,MAAM,KAAG,MAAM;iCAEvB,MAAM,KAAG,MAAM;4CACJ,MAAM,gBAAgB,MAAM,KAAG,MAAM;sCAE3C,MAAM,gBAAgB,MAAM,gBAAgB,MAAM,KAAG,MAAM;;;wDAIzC,MAAM,qBAAqB,MAAM,KAAG,MAAM;4CAEtD,MAAM,qBAAqB,MAAM,KAAG,MAAM;;;yCAI7C,MAAM,aAAa,MAAM,QAAQ,MAAM,EAAE,KAAG,MAAM;2CAIhD,MAAM,aAAa,MAAM,QAAQ,MAAM,EAAE,KAAG,MAAM;sDAEvC,MAAM,QAAQ,MAAM,EAAE,KAAG,MAAM;8DAEvB,MAAM,aAAa,MAAM,cAAc,MAAM,KAAG,MAAM;6EAEvC,MAAM,qBAAqB,MAAM,KAAG,MAAM;yEAE9C,MAAM,qBAAqB,MAAM,KAAG,MAAM;;wCAG/E,MAAM;sDACU,MAAM,KAAG,MAAM;iDAEpB,MAAM,KAAG,MAAM;2DAEL,MAAM,KAAG,MAAM;0CAEhC,MAAM,OAAO,MAAM,KAAG,MAAM;yDAEb,MAAM,KAAG,MAAM;uEAED,MAAM,KAAG,MAAM;;;;mCAKjD,MAAM,KAAG,MAAM;mCAEf,MAAM,KAAG,MAAM;;;qCAIb,MAAM,KAAG,MAAM;;;0CAIV,MAAM,KAAG,MAAM;;;4CAIb,MAAM,EAAE,KAAG,MAAM;;;wCAIrB,cAAc,OAAO,MAAM,UAAU,MAAM,EAAE,KAAG,MAAM;;;mCAI3D,MAAM,EAAE,KAAG,MAAM;;;4DAIQ,MAAM,KAAG,MAAM;qCAEtC,MAAM,KAAG,MAAM;2CAET,MAAM,KAAG,MAAM;;;oCAGtB,MAAM,KAAG,MAAM;;oCAEjB,MAAM,SAAS,MAAM,KAAG,MAAM;qCAI7B,MAAM,YAAY,MAAM,KAAG,MAAM;;;;;iCAQrC,MAAM,KAAG,MAAM;;;;oDAKI,MAAM;8DACM,MAAM,qBAAqB,MAAM,KAAG,MAAM;kDAEtD,MAAM,qBAAqB,MAAM,KAAG,MAAM;;;wDAIpC,MAAM,KAAG,MAAM;;;;kCAKnC,MAAM,OAAO,MAAM,KAAG,MAAM;iCAE7B,MAAM,OAAO,MAAM,KAAG,MAAM;oCAEzB,MAAM,OAAO,MAAM,KAAG,MAAM;gDAEhB,MAAM,KAAG,MAAM;uCAExB,MAAM,KAAG,MAAM;+BACvB,MAAM,OAAO,MAAM,KAAG,MAAM;;;;;;;;kCASzB,MAAM,UAAU,MAAM,KAAG,MAAM;gCAEjC,MAAM,KAAG,MAAM;2CAEJ,MAAM,eAAe,MAAM,KAAG,MAAM;;;uCAI1C,MAAM;uCAEJ,MAAM,KAAG,MAAM;qCAEnB,MAAM;;6CAGA,MAAM;;;mDAIE,MAAM,KAAG,MAAM;;;;4CAKxB,MAAM,SAAS,MAAM,KAAG,MAAM;4CAE9B,MAAM,KAAG,MAAM;4CACf,MAAM,SAAS,MAAM,KAAG,MAAM;+CAE3B,MAAM,aAAa,MAAM,SAAS,MAAM,KAAG,MAAM;yCAEvD,MAAM,SAAS,MAAM,KAAG,MAAM;4CAE3B,MAAM,SAAS,MAAM,KAAG,MAAM;gDAE1B,MAAM,aAAa,MAAM,KAAG,MAAM;4CAEtC,MAAM,SAAS,MAAM,KAAG,MAAM;;;2CAI7B,MAAM;;;gCAInB,MAAM;;;;CAI7B,CAAC;AAEF,oBAAY,UAAU;IACpB,eAAe,2BAA2B;IAC1C,eAAe,wBAAwB;IACvC,WAAW,4BAA4B;IACvC,WAAW,+BAA+B;IAC1C,aAAa,8BAA8B;IAC3C,OAAO,0BAA0B;IACjC,cAAc,kCAAkC;IAChD,mBAAmB,0BAA0B;IAC7C,SAAS,4BAA4B;IACrC,SAAS,4BAA4B;IACrC,UAAU,wBAAwB;IAClC,GAAG,8BAA8B;IACjC,eAAe,0BAA0B;CAC1C"}
|
package/out/text/errors.js
CHANGED
|
@@ -21,7 +21,8 @@ exports.errors = {
|
|
|
21
21
|
additionalProperties: (additionalProperty) => `should NOT have additional property '${additionalProperty}'`,
|
|
22
22
|
notAllowed: (props) => props
|
|
23
23
|
? `does not support the following Forge properties - ${props.map((v) => "'" + v + "'").join(', ')}`
|
|
24
|
-
: 'provided properties do not match schema. Learn more about modules at https://go.atlassian.com/forge-modules'
|
|
24
|
+
: 'provided properties do not match schema. Learn more about modules at https://go.atlassian.com/forge-modules',
|
|
25
|
+
missingEnvironmentVariable: (variable) => `could not find environment variable '${variable}'`
|
|
25
26
|
},
|
|
26
27
|
permissions: {
|
|
27
28
|
invalidPermission: (element, value) => `Invalid '${element}' permission in the manifest.yml file - '${value}'. Learn more about permissions at: https://go.atlassian.com/forge-permissions.`,
|
package/out/utils/index.d.ts
CHANGED
package/out/utils/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
|
package/out/utils/index.js
CHANGED
|
@@ -5,3 +5,4 @@ tslib_1.__exportStar(require("./get-all-modules"), exports);
|
|
|
5
5
|
tslib_1.__exportStar(require("./line-finder"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./module-key-cleaner"), exports);
|
|
7
7
|
tslib_1.__exportStar(require("./module-references"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./manifest-parser"), exports);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ManifestSchema } from '../schema/manifest';
|
|
2
|
+
export declare class ManifestParserError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
getAttributes(): {
|
|
5
|
+
isUserError: boolean;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export declare class ManifestParser {
|
|
9
|
+
private readonly envVarsRecord;
|
|
10
|
+
private envVarsToReplace;
|
|
11
|
+
constructor(envVarsRecord?: Record<string, string | undefined>);
|
|
12
|
+
parseManifest(manifest: string): ManifestSchema;
|
|
13
|
+
parseManifestAsString: (manifest: string) => string;
|
|
14
|
+
private environmentVariableReviver;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=manifest-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-parser.d.ts","sourceRoot":"","sources":["../../src/utils/manifest-parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKpD,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;IAMpB,aAAa;;;CAKrB;AAMD,qBAAa,cAAc;IAGb,OAAO,CAAC,QAAQ,CAAC,aAAa;IAF1C,OAAO,CAAC,gBAAgB,CAAW;gBAEN,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAM;IAI5E,aAAa,CAAC,QAAQ,EAAE,MAAM;IAMrC,qBAAqB,aAAc,MAAM,YAAgE;IAEzG,OAAO,CAAC,0BAA0B,CAkBhC;CACH"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ManifestParser = exports.ManifestParserError = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const yaml_1 = require("yaml");
|
|
6
|
+
const errors_1 = require("../text/errors");
|
|
7
|
+
const Sentry = tslib_1.__importStar(require("@sentry/node"));
|
|
8
|
+
const yamlConfigOptions = { indent: 2, skipInvalid: true };
|
|
9
|
+
class ManifestParserError extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
}
|
|
13
|
+
getAttributes() {
|
|
14
|
+
return {
|
|
15
|
+
isUserError: true
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ManifestParserError = ManifestParserError;
|
|
20
|
+
const POSSIBLE_ENVIRONMENT_VARIABLE = /\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
|
|
21
|
+
class ManifestParser {
|
|
22
|
+
envVarsRecord;
|
|
23
|
+
envVarsToReplace;
|
|
24
|
+
constructor(envVarsRecord = {}) {
|
|
25
|
+
this.envVarsRecord = envVarsRecord;
|
|
26
|
+
this.envVarsToReplace = [];
|
|
27
|
+
}
|
|
28
|
+
parseManifest(manifest) {
|
|
29
|
+
const rawManifest = (0, yaml_1.parse)(manifest);
|
|
30
|
+
this.envVarsToReplace = rawManifest.environment?.variables ?? [];
|
|
31
|
+
return (0, yaml_1.parse)(manifest, this.environmentVariableReviver);
|
|
32
|
+
}
|
|
33
|
+
parseManifestAsString = (manifest) => (0, yaml_1.stringify)(this.parseManifest(manifest), yamlConfigOptions);
|
|
34
|
+
environmentVariableReviver = (_, value) => {
|
|
35
|
+
if (!(typeof value == 'string')) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
value = value.replaceAll(POSSIBLE_ENVIRONMENT_VARIABLE, (original, envVarName) => {
|
|
39
|
+
if (!this.envVarsToReplace.includes(envVarName)) {
|
|
40
|
+
return original;
|
|
41
|
+
}
|
|
42
|
+
const envVar = this.envVarsRecord[envVarName];
|
|
43
|
+
if (envVar === undefined) {
|
|
44
|
+
throw new ManifestParserError(errors_1.errors.schema.missingEnvironmentVariable(envVarName));
|
|
45
|
+
}
|
|
46
|
+
Sentry.captureMessage('replaced environment variable');
|
|
47
|
+
return envVar;
|
|
48
|
+
});
|
|
49
|
+
return value;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
exports.ManifestParser = ManifestParser;
|
|
@@ -4,7 +4,7 @@ exports.findInvalidEndpointReferences = exports.findInvalidResourceReferences =
|
|
|
4
4
|
const findInvalidReferenceKeys = (property, module, functionsOrResources) => {
|
|
5
5
|
const invalidFunctions = [];
|
|
6
6
|
const _checkFunctionKey = (functionKey) => {
|
|
7
|
-
if (functionKey && !
|
|
7
|
+
if (functionKey && !functionsOrResources?.find((func) => func.key === functionKey)) {
|
|
8
8
|
invalidFunctions.push(functionKey);
|
|
9
9
|
}
|
|
10
10
|
};
|
|
@@ -5,11 +5,15 @@ const text_1 = require("../text");
|
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
class AppFeaturesValidator {
|
|
7
7
|
async validate(manifest) {
|
|
8
|
-
|
|
9
|
-
const app = (_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a.app;
|
|
8
|
+
const app = manifest?.typedContent?.app;
|
|
10
9
|
const validationErrors = [];
|
|
11
|
-
if (
|
|
12
|
-
validationErrors.push(
|
|
10
|
+
if (app?.features?.autoUserConsent !== undefined) {
|
|
11
|
+
validationErrors.push({
|
|
12
|
+
message: text_1.errors.app.features.deprecatedAutoUserConsent(),
|
|
13
|
+
reference: text_1.References.Deprecated,
|
|
14
|
+
level: 'warning',
|
|
15
|
+
...(0, utils_1.findPosition)('autoUserConsent', manifest?.yamlContentByLine)
|
|
16
|
+
});
|
|
13
17
|
}
|
|
14
18
|
return {
|
|
15
19
|
success: validationErrors.length === 0,
|
|
@@ -5,8 +5,7 @@ const text_1 = require("../text");
|
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
class ConnectAuthenticationValidator {
|
|
7
7
|
async validate(manifest) {
|
|
8
|
-
|
|
9
|
-
if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a.app)) {
|
|
8
|
+
if (!manifest?.typedContent?.app) {
|
|
10
9
|
return {
|
|
11
10
|
success: false,
|
|
12
11
|
manifestObject: manifest
|
|
@@ -14,8 +13,13 @@ class ConnectAuthenticationValidator {
|
|
|
14
13
|
}
|
|
15
14
|
const app = manifest.typedContent.app;
|
|
16
15
|
const validationErrors = [];
|
|
17
|
-
if (!manifest.typedContent.connectModules &&
|
|
18
|
-
validationErrors.push(
|
|
16
|
+
if (!manifest.typedContent.connectModules && app?.connect?.authentication) {
|
|
17
|
+
validationErrors.push({
|
|
18
|
+
message: text_1.errors.app.missingConnectModules(),
|
|
19
|
+
reference: text_1.References.App,
|
|
20
|
+
level: 'error',
|
|
21
|
+
...(0, utils_1.findPosition)('connect', manifest.yamlContentByLine)
|
|
22
|
+
});
|
|
19
23
|
}
|
|
20
24
|
return {
|
|
21
25
|
success: validationErrors.length === 0,
|
|
@@ -20,20 +20,35 @@ class ConnectModulesValidator {
|
|
|
20
20
|
connectModuleNames
|
|
21
21
|
.filter((name) => !validconnectModuleNames.includes(name))
|
|
22
22
|
.forEach((invalidName) => {
|
|
23
|
-
validationErrors.push(
|
|
23
|
+
validationErrors.push({
|
|
24
|
+
message: text_1.errors.connectModules.invalidConnectModule(invalidName),
|
|
25
|
+
reference: text_1.References.ConnectModules,
|
|
26
|
+
level: 'error',
|
|
27
|
+
...(0, utils_1.findPosition)(invalidName, yamlContentByLine, 'connectModules')
|
|
28
|
+
});
|
|
24
29
|
});
|
|
25
30
|
const modules = connectModuleNames.map((moduleName) => connectModules[moduleName]);
|
|
26
31
|
const moduleKeys = [].concat(...modules).map((item) => item.key);
|
|
27
32
|
const duplicateKeys = [...new Set(moduleKeys.filter((item, index) => moduleKeys.indexOf(item) != index))];
|
|
28
33
|
duplicateKeys.forEach((duplicateKey) => {
|
|
29
|
-
validationErrors.push(
|
|
34
|
+
validationErrors.push({
|
|
35
|
+
message: text_1.errors.connectModules.duplicateKeyFound(duplicateKey),
|
|
36
|
+
reference: text_1.References.ConnectModules,
|
|
37
|
+
level: 'error',
|
|
38
|
+
...(0, utils_1.findPosition)(duplicateKey, yamlContentByLine)
|
|
39
|
+
});
|
|
30
40
|
});
|
|
31
41
|
const lifecycleModules = connectModuleNames.filter((m) => m.endsWith(':lifecycle'));
|
|
32
42
|
if (lifecycleModules) {
|
|
33
43
|
lifecycleModules.forEach((lifecycle) => {
|
|
34
44
|
const lifecycleModule = connectModules[lifecycle];
|
|
35
45
|
if (Array.isArray(lifecycleModule) && lifecycleModule.length > 1) {
|
|
36
|
-
validationErrors.push(
|
|
46
|
+
validationErrors.push({
|
|
47
|
+
message: text_1.errors.connectModules.duplicatateLifecycleFound(lifecycle),
|
|
48
|
+
reference: text_1.References.ConnectModules,
|
|
49
|
+
level: 'error',
|
|
50
|
+
...(0, utils_1.findPosition)(lifecycle, yamlContentByLine)
|
|
51
|
+
});
|
|
37
52
|
}
|
|
38
53
|
});
|
|
39
54
|
}
|
|
@@ -5,8 +5,7 @@ const text_1 = require("../text");
|
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
class ConnectRemoteValidator {
|
|
7
7
|
async validate(manifest) {
|
|
8
|
-
|
|
9
|
-
if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a.app)) {
|
|
8
|
+
if (!manifest?.typedContent?.app) {
|
|
10
9
|
return {
|
|
11
10
|
success: false,
|
|
12
11
|
manifestObject: manifest
|
|
@@ -14,13 +13,23 @@ class ConnectRemoteValidator {
|
|
|
14
13
|
}
|
|
15
14
|
const app = manifest.typedContent.app;
|
|
16
15
|
const validationErrors = [];
|
|
17
|
-
if (manifest.typedContent.connectModules && !
|
|
18
|
-
validationErrors.push(
|
|
16
|
+
if (manifest.typedContent.connectModules && !app.connect?.remote) {
|
|
17
|
+
validationErrors.push({
|
|
18
|
+
message: text_1.errors.app.missingAppConnectRemote(),
|
|
19
|
+
reference: text_1.References.App,
|
|
20
|
+
level: 'error',
|
|
21
|
+
...(0, utils_1.findPosition)('connect', manifest.yamlContentByLine)
|
|
22
|
+
});
|
|
19
23
|
}
|
|
20
24
|
if (manifest.typedContent.connectModules &&
|
|
21
|
-
|
|
22
|
-
!
|
|
23
|
-
validationErrors.push(
|
|
25
|
+
app?.connect?.remote &&
|
|
26
|
+
!manifest.typedContent.remotes?.find((remote) => remote.key === app?.connect?.remote)) {
|
|
27
|
+
validationErrors.push({
|
|
28
|
+
message: text_1.errors.app.missingRemoteForConnect(app?.connect?.remote || 'undefined'),
|
|
29
|
+
reference: text_1.References.App,
|
|
30
|
+
level: 'error',
|
|
31
|
+
...(0, utils_1.findPosition)('connect', manifest.yamlContentByLine)
|
|
32
|
+
});
|
|
24
33
|
}
|
|
25
34
|
return {
|
|
26
35
|
success: validationErrors.length === 0,
|
|
@@ -5,8 +5,7 @@ const text_1 = require("../text");
|
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
class DataClassificationValidator {
|
|
7
7
|
async validate(manifest) {
|
|
8
|
-
|
|
9
|
-
if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a.remotes)) {
|
|
8
|
+
if (!manifest?.typedContent?.remotes) {
|
|
10
9
|
return {
|
|
11
10
|
success: true,
|
|
12
11
|
manifestObject: manifest
|
|
@@ -14,9 +13,13 @@ class DataClassificationValidator {
|
|
|
14
13
|
}
|
|
15
14
|
const validationErrors = [];
|
|
16
15
|
manifest.typedContent.remotes.forEach((remote) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if (remote.operations && remote.operations.includes('storage') && remote.storage?.inScopeEUD === undefined) {
|
|
17
|
+
validationErrors.push({
|
|
18
|
+
message: text_1.errors.app.remotes.missingRemotesStorageInScopeEUD(remote.key),
|
|
19
|
+
reference: text_1.References.App,
|
|
20
|
+
level: 'error',
|
|
21
|
+
...(0, utils_1.findPosition)(remote.key, manifest.yamlContentByLine)
|
|
22
|
+
});
|
|
20
23
|
}
|
|
21
24
|
});
|
|
22
25
|
return {
|
|
@@ -7,14 +7,17 @@ const text_1 = require("../text");
|
|
|
7
7
|
const isPlainObject = (obj) => Object.prototype.toString.call(obj) === '[object Object]';
|
|
8
8
|
const errors = text_1.errors.modules.displayConditions;
|
|
9
9
|
class DisplayConditionsValidator {
|
|
10
|
+
schema;
|
|
11
|
+
validateSchema;
|
|
12
|
+
moduleSchemas;
|
|
13
|
+
supportedOperations;
|
|
10
14
|
constructor(schema) {
|
|
11
|
-
var _a, _b, _c;
|
|
12
15
|
this.schema = schema;
|
|
13
16
|
const ajv = new ajv_1.default({ allErrors: true, verbose: true, strict: false });
|
|
14
17
|
this.validateSchema = ajv.compile(this.schema);
|
|
15
18
|
const properties = this.schema.properties;
|
|
16
|
-
this.moduleSchemas =
|
|
17
|
-
this.supportedOperations =
|
|
19
|
+
this.moduleSchemas = properties.modules?.properties;
|
|
20
|
+
this.supportedOperations = properties.operations?.items?.enum;
|
|
18
21
|
}
|
|
19
22
|
flattenDisplayConditions(moduleKey, displayConditions, nesting = 0) {
|
|
20
23
|
if (nesting >= 10) {
|
|
@@ -69,8 +72,7 @@ class DisplayConditionsValidator {
|
|
|
69
72
|
}
|
|
70
73
|
};
|
|
71
74
|
Object.keys(this.moduleSchemas).forEach((m) => {
|
|
72
|
-
|
|
73
|
-
(_a = modules[m]) === null || _a === void 0 ? void 0 : _a.forEach((module) => {
|
|
75
|
+
modules[m]?.forEach((module) => {
|
|
74
76
|
if (!module.displayConditions) {
|
|
75
77
|
return;
|
|
76
78
|
}
|
|
@@ -87,9 +89,8 @@ class DisplayConditionsValidator {
|
|
|
87
89
|
return;
|
|
88
90
|
}
|
|
89
91
|
displayConditions.forEach((result) => {
|
|
90
|
-
var _a;
|
|
91
92
|
void this.validateSchema({ modules: { [m]: result } });
|
|
92
|
-
|
|
93
|
+
this.validateSchema.errors?.forEach((error) => {
|
|
93
94
|
const { keyword, instancePath, params, message } = error;
|
|
94
95
|
const split = instancePath.split('/');
|
|
95
96
|
const path = String(split.pop());
|
|
@@ -5,18 +5,21 @@ const types_1 = require("../types");
|
|
|
5
5
|
const text_1 = require("../text");
|
|
6
6
|
const utils_1 = require("../utils");
|
|
7
7
|
const isManifestWithModules = (manifest) => {
|
|
8
|
-
|
|
9
|
-
return !!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a['modules']);
|
|
8
|
+
return !!manifest?.typedContent?.['modules'];
|
|
10
9
|
};
|
|
11
10
|
class EntityPropertyValidator {
|
|
12
11
|
async validate(manifest) {
|
|
13
|
-
var _a;
|
|
14
12
|
const validationErrors = [];
|
|
15
|
-
if (
|
|
13
|
+
if (manifest?.typedContent && isManifestWithModules(manifest)) {
|
|
16
14
|
const { yamlContentByLine, typedContent: { modules } } = manifest;
|
|
17
|
-
const appValuesLength =
|
|
15
|
+
const appValuesLength = modules[types_1.AllModuleTypes.JiraEntityProperty]?.reduce((acc, module) => acc + module.values.length, 0) || 0;
|
|
18
16
|
if (appValuesLength > 30) {
|
|
19
|
-
validationErrors.push(
|
|
17
|
+
validationErrors.push({
|
|
18
|
+
message: text_1.errors.modules.jiraEntityProperty.maxExtractionsPerApp(30),
|
|
19
|
+
reference: text_1.References.Modules,
|
|
20
|
+
level: 'error',
|
|
21
|
+
...(0, utils_1.findPosition)('app', yamlContentByLine)
|
|
22
|
+
});
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
return {
|
|
@@ -5,16 +5,14 @@ const types_1 = require("../types");
|
|
|
5
5
|
const text_1 = require("../text");
|
|
6
6
|
const utils_1 = require("../utils");
|
|
7
7
|
const isManifestWithModules = (manifest) => {
|
|
8
|
-
|
|
9
|
-
return !!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.typedContent) === null || _a === void 0 ? void 0 : _a['modules']);
|
|
8
|
+
return !!manifest?.typedContent?.['modules'];
|
|
10
9
|
};
|
|
11
10
|
class JqlFunctionValidator {
|
|
12
11
|
async validate(manifest) {
|
|
13
|
-
var _a;
|
|
14
12
|
const validationErrors = [];
|
|
15
|
-
if (
|
|
13
|
+
if (manifest?.typedContent && isManifestWithModules(manifest)) {
|
|
16
14
|
const { yamlContentByLine, typedContent: { modules } } = manifest;
|
|
17
|
-
const functionNames =
|
|
15
|
+
const functionNames = modules[types_1.AllModuleTypes.JiraJqlFunction]?.map((m) => m.name) || [];
|
|
18
16
|
const lowerCaseFunctionNames = functionNames.map((name) => name.toLowerCase());
|
|
19
17
|
const lowerCaseNameToActualName = {};
|
|
20
18
|
const lowerCaseDuplicateNames = [
|
|
@@ -26,7 +24,12 @@ class JqlFunctionValidator {
|
|
|
26
24
|
}))
|
|
27
25
|
];
|
|
28
26
|
if (lowerCaseDuplicateNames.length > 0) {
|
|
29
|
-
validationErrors.push(
|
|
27
|
+
validationErrors.push({
|
|
28
|
+
message: text_1.errors.modules.jiraJqlFunction.duplicateFunctionNames(lowerCaseDuplicateNames.map((lowerCaseName) => lowerCaseNameToActualName[lowerCaseName])),
|
|
29
|
+
reference: text_1.References.Modules,
|
|
30
|
+
level: 'error',
|
|
31
|
+
...(0, utils_1.findPosition)(lowerCaseNameToActualName[lowerCaseDuplicateNames[0]], yamlContentByLine)
|
|
32
|
+
});
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
return {
|