npm package diff

Package: @forge/manifest

Versions: 9.1.0-next.3 - 9.1.0-next.4

File: package/out/validators/modules-validator.js

Index: package/out/validators/modules-validator.js
===================================================================
--- package/out/validators/modules-validator.js
+++ package/out/validators/modules-validator.js
@@ -30,10 +30,10 @@
             };
         }
         let validationErrors = [...this.connectModuleValidation(manifest)];
         if (manifest.typedContent.modules) {
-            const { typedContent: { modules, connectModules, remotes, permissions }, yamlContentByLine, filePath } = manifest;
-            validationErrors = validationErrors.concat(this.checkUnsupportedModules(manifest.typedContent.modules, yamlContentByLine), this.functionKeyLength(modules, yamlContentByLine), this.minimumModuleCountValidation(modules, yamlContentByLine), this.functionKeyDefinedValidation(modules, yamlContentByLine), this.endpointValidations(modules, yamlContentByLine, remotes, permissions?.scopes || []), this.duplicateModuleKeyValidation(modules, connectModules || {}, yamlContentByLine), this.functionHandlerValidation(modules, yamlContentByLine, filePath), (0, validate_workflow_1.validateJiraWorkflowValidator)(modules, yamlContentByLine), (0, validate_workflow_1.validateJiraWorkflowCondition)(modules, yamlContentByLine), (0, ui_modifications_1.validateUiModificationsModule)(modules, yamlContentByLine), (0, validate_full_admin_page_1.validateJiraFullAdminPage)(modules, yamlContentByLine), (0, validate_full_page_1.validateJiraFullPage)(modules, yamlContentByLine), (0, validate_custom_field_1.validateJiraCustomField)(modules, yamlContentByLine), (0, confluence_1.validateConfluenceModules)(modules, yamlContentByLine), (0, bitbucket_1.validateBitbucketModules)(modules, yamlContentByLine), (0, validate_trigger_1.validateJiraTriggers)(modules, yamlContentByLine), (0, remote_1.validateRemoteModules)(modules, yamlContentByLine), (0, dataResidency_1.validateMigrationDataResidencyModule)(modules, remotes, yamlContentByLine), (0, validateModuleScopes_1.validateModuleScopes)(modules, yamlContentByLine, permissions), (0, rovo_1.validateRovoModules)(modules, yamlContentByLine), (0, validate_timetrackingprovider_module_1.validateJiraTimeTrackingModule)(modules, yamlContentByLine), (0, validate_command_1.validateJiraCommandModule)(modules, yamlContentByLine));
+            const { typedContent: { modules, connectModules, remotes, permissions, services }, yamlContentByLine, filePath } = manifest;
+            validationErrors = validationErrors.concat(this.checkUnsupportedModules(manifest.typedContent.modules, yamlContentByLine), this.functionKeyLength(modules, yamlContentByLine), this.minimumModuleCountValidation(modules, yamlContentByLine), this.functionKeyDefinedValidation(modules, yamlContentByLine), this.endpointValidations(modules, yamlContentByLine, remotes, permissions?.scopes || [], services), this.duplicateModuleKeyValidation(modules, connectModules || {}, yamlContentByLine), this.functionHandlerValidation(modules, yamlContentByLine, filePath), (0, validate_workflow_1.validateJiraWorkflowValidator)(modules, yamlContentByLine), (0, validate_workflow_1.validateJiraWorkflowCondition)(modules, yamlContentByLine), (0, ui_modifications_1.validateUiModificationsModule)(modules, yamlContentByLine), (0, validate_full_admin_page_1.validateJiraFullAdminPage)(modules, yamlContentByLine), (0, validate_full_page_1.validateJiraFullPage)(modules, yamlContentByLine), (0, validate_custom_field_1.validateJiraCustomField)(modules, yamlContentByLine), (0, confluence_1.validateConfluenceModules)(modules, yamlContentByLine), (0, bitbucket_1.validateBitbucketModules)(modules, yamlContentByLine), (0, validate_trigger_1.validateJiraTriggers)(modules, yamlContentByLine), (0, remote_1.validateRemoteModules)(modules, yamlContentByLine), (0, dataResidency_1.validateMigrationDataResidencyModule)(modules, remotes, yamlContentByLine), (0, validateModuleScopes_1.validateModuleScopes)(modules, yamlContentByLine, permissions), (0, rovo_1.validateRovoModules)(modules, yamlContentByLine), (0, validate_timetrackingprovider_module_1.validateJiraTimeTrackingModule)(modules, yamlContentByLine), (0, validate_command_1.validateJiraCommandModule)(modules, yamlContentByLine));
         }
         else {
             const { typedContent: { connectModules }, yamlContentByLine } = manifest;
             validationErrors = validationErrors.concat(this.duplicateModuleKeyValidation({}, connectModules || {}, yamlContentByLine));
@@ -124,9 +124,9 @@
             });
         });
         return validationErrors;
     }
-    endpointValidations(modules, yamlContentByLine, remotes, scopes) {
+    endpointValidations(modules, yamlContentByLine, remotes, scopes, services) {
         const validationErrors = [];
         const _checkRemoteExists = (remoteKey) => {
             return remotes?.find((remote) => remote.key === remoteKey) !== undefined;
         };
@@ -155,42 +155,54 @@
         });
         function isRemoteType(obj) {
             return obj && typeof obj === 'object' && 'remote' in obj;
         }
+        function isServiceType(obj) {
+            return obj && typeof obj === 'object' && 'service' in obj;
+        }
         _endpoint?.forEach((endpoint) => {
-            if (!isRemoteType(endpoint)) {
-                return;
+            if (isRemoteType(endpoint)) {
+                if (!_checkRemoteExists(endpoint.remote)) {
+                    validationErrors.push({
+                        message: text_1.errors.modules.endpoint.remote.notExists(endpoint.remote),
+                        reference: text_1.References.Modules,
+                        level: 'error',
+                        ...(0, utils_1.findPosition)(endpoint.remote, yamlContentByLine)
+                    });
+                }
+                if (endpoint.auth?.appUserToken?.enabled && !scopes.includes(types_1.USER_TOKEN_SCOPE)) {
+                    validationErrors.push({
+                        message: text_1.errors.permissions.missingEndpointPermissionFromScope(types_1.USER_TOKEN_SCOPE, endpoint.key),
+                        reference: text_1.References.MissingScopes,
+                        level: 'error',
+                        metadata: {
+                            missingPermission: types_1.USER_TOKEN_SCOPE
+                        },
+                        ...(0, utils_1.findPosition)('scopes', yamlContentByLine)
+                    });
+                }
+                if (endpoint.auth?.appSystemToken?.enabled && !scopes.includes(types_1.SYSTEM_TOKEN_SCOPE)) {
+                    validationErrors.push({
+                        message: text_1.errors.permissions.missingEndpointPermissionFromScope(types_1.SYSTEM_TOKEN_SCOPE, endpoint.key),
+                        reference: text_1.References.MissingScopes,
+                        level: 'error',
+                        metadata: {
+                            missingPermission: types_1.SYSTEM_TOKEN_SCOPE
+                        },
+                        ...(0, utils_1.findPosition)('scopes', yamlContentByLine)
+                    });
+                }
             }
-            if (!_checkRemoteExists(endpoint.remote)) {
-                validationErrors.push({
-                    message: text_1.errors.modules.endpoint.remote.notExists(endpoint.remote),
-                    reference: text_1.References.Modules,
-                    level: 'error',
-                    ...(0, utils_1.findPosition)(endpoint.remote, yamlContentByLine)
+            else if (isServiceType(endpoint)) {
+                (0, utils_1.findInvalidServiceReferences)(endpoint, services).forEach((service) => {
+                    validationErrors.push({
+                        message: text_1.errors.modules.wrongServiceReference('endpoint', service),
+                        reference: text_1.References.Modules,
+                        level: 'error',
+                        ...(0, utils_1.findPosition)('endpoint', yamlContentByLine)
+                    });
                 });
             }
-            if (endpoint.auth?.appUserToken?.enabled && !scopes.includes(types_1.USER_TOKEN_SCOPE)) {
-                validationErrors.push({
-                    message: text_1.errors.permissions.missingEndpointPermissionFromScope(types_1.USER_TOKEN_SCOPE, endpoint.key),
-                    reference: text_1.References.MissingScopes,
-                    level: 'error',
-                    metadata: {
-                        missingPermission: types_1.USER_TOKEN_SCOPE
-                    },
-                    ...(0, utils_1.findPosition)('scopes', yamlContentByLine)
-                });
-            }
-            if (endpoint.auth?.appSystemToken?.enabled && !scopes.includes(types_1.SYSTEM_TOKEN_SCOPE)) {
-                validationErrors.push({
-                    message: text_1.errors.permissions.missingEndpointPermissionFromScope(types_1.SYSTEM_TOKEN_SCOPE, endpoint.key),
-                    reference: text_1.References.MissingScopes,
-                    level: 'error',
-                    metadata: {
-                        missingPermission: types_1.SYSTEM_TOKEN_SCOPE
-                    },
-                    ...(0, utils_1.findPosition)('scopes', yamlContentByLine)
-                });
-            }
         });
         remotes?.forEach((remote) => {
             if (remote.auth?.appUserToken?.enabled && !scopes.includes(types_1.USER_TOKEN_SCOPE)) {
                 validationErrors.push({