From 29ec2fcc963f2ba0840dc28fd17f9bda9bd00cb6 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 22 Aug 2023 00:02:39 +0100 Subject: [PATCH] [ACS-5845] remove Alfresco Compatibility usage (#8822) * upgrade to latest js-api * upgrade to latest js-api * upgrade to latest js-api * upgrade to latest js-api * upgrade to latest js-api * upgrade to latest js-api * fix security concerns for execSync * security fix * fixes as per code reviews * code fixes for attach file widget dialog * code fixes * code fixes * disable ACS storage check * add the jira to the commented out block * remove useless logger call * code fixes * code fixes * code fixes * code and typing fixes * fix lint * disable the code * try other fixes, add missing headers * dump error to console * replace test file with in-memory stream * code fixes * simplify checks * disable upload * remove useless test and ng-mocks dependency --- e2e/protractor/save-remote.js | 71 ++--- lib/cli/scripts/check-cs-env.ts | 108 +++---- lib/cli/scripts/check-ps-env.ts | 40 ++- lib/cli/scripts/init-aae-env.ts | 267 ++++++++++++------ lib/cli/scripts/init-acs-env.ts | 106 ++++--- lib/cli/scripts/init-aps-env.ts | 115 ++++---- lib/cli/scripts/kubectl-clean-app.ts | 150 +++++++--- lib/cli/scripts/plugins/check-env.ts | 36 ++- .../plugins/governance-check-plugin.ts | 6 +- lib/cli/scripts/plugins/governance-health.ts | 38 +-- lib/cli/scripts/plugins/plugin-config.ts | 11 +- .../process-automation-check-plugin.ts | 42 ++- .../plugins/process-automation-health.ts | 35 +-- .../plugins/process-service-check-plugin.ts | 37 +-- .../plugins/process-services-health.ts | 31 +- lib/cli/scripts/scan-env.ts | 78 +++-- .../mock/download-zip-service.mock.ts | 4 +- ...hentication-confirmation.component.spec.ts | 51 ---- .../services/external-alfresco-api.service.ts | 47 +-- .../attach-file-widget-dialog.component.ts | 31 +- .../form/widgets/document/content.widget.ts | 39 ++- package-lock.json | 15 - package.json | 2 - 23 files changed, 683 insertions(+), 677 deletions(-) delete mode 100644 lib/core/src/lib/auth/oidc/view/authentication-confirmation/authentication-confirmation.component.spec.ts diff --git a/e2e/protractor/save-remote.js b/e2e/protractor/save-remote.js index 4ebf4c262e3..fae7821032a 100644 --- a/e2e/protractor/save-remote.js +++ b/e2e/protractor/save-remote.js @@ -1,8 +1,8 @@ -const fs = require('fs'); -const rimraf = require('rimraf'); -const path = require('path'); +const { spawnSync } = require('node:child_process'); +const fs = require('node:fs'); +const path = require('node:path'); const TestConfig = require('../test.config'); -const AlfrescoApi = require('@alfresco/js-api').AlfrescoApiCompatibility; +const { AlfrescoApi, NodesApi, UploadApi } = require('@alfresco/js-api'); function buildNumber() { let buildNumber = process.env.GH_BUILD_NUMBER; @@ -16,54 +16,57 @@ function buildNumber() { async function uploadScreenshot(retryCount, suffixFileName) { console.log(`Start uploading report ${retryCount}`); - let alfrescoJsApi = new AlfrescoApi({ + const alfrescoJsApi = new AlfrescoApi({ provider: 'ECM', hostEcm: TestConfig.screenshot.url }); + const nodesApi = new NodesApi(alfrescoJsApi); + const uploadApi = new UploadApi(alfrescoJsApi); + await alfrescoJsApi.login(TestConfig.users.screenshot.username, TestConfig.users.screenshot.password); let folderNode; try { - folderNode = await alfrescoJsApi.nodes.addNode('-my-', { - 'name': `retry-${retryCount}`, - 'relativePath': `Builds/${buildNumber()}/`, - 'nodeType': 'cm:folder' - }, {}, { - 'overwrite': true - }); + folderNode = await nodesApi.createNode( + '-my-', + { + name: `retry-${retryCount}`, + relativePath: `Builds/${buildNumber()}/`, + nodeType: 'cm:folder' + }, + {}, + { + overwrite: true + } + ); } catch (error) { - folderNode = await alfrescoJsApi.nodes.getNode('-my-', { - 'relativePath': `Builds/${buildNumber()}/retry-${retryCount}`, - 'nodeType': 'cm:folder' - }, {}, { - 'overwrite': true + folderNode = await nodesApi.getNode('-my-', { + relativePath: `Builds/${buildNumber()}/retry-${retryCount}` }); } suffixFileName = suffixFileName.replace(/\//g, '-'); - fs.renameSync(path.resolve(__dirname, '../../e2e-output/'), path.resolve(__dirname, `../../e2e-output-${retryCount}-${process.env.GH_ACTION_RETRY_COUNT}/`)) + fs.renameSync( + path.resolve(__dirname, '../../e2e-output/'), + path.resolve(__dirname, `../../e2e-output-${retryCount}-${process.env.GH_ACTION_RETRY_COUNT}/`) + ); - const child_process = require("child_process"); - child_process.execSync(` tar -czvf ../e2e-result-${suffixFileName}-${retryCount}.tar .`, { - cwd: path.resolve(__dirname, `../../e2e-output-${retryCount}-${process.env.GH_ACTION_RETRY_COUNT}/`) + spawnSync(` tar -czvf ../e2e-result-${suffixFileName}-${retryCount}.tar .`, { + cwd: path.resolve(__dirname, `../../e2e-output-${retryCount}-${process.env.GH_ACTION_RETRY_COUNT}/`), + shell: false }); - let pathFile = path.join(__dirname, `../../e2e-result-${suffixFileName}-${retryCount}.tar`); - let file = fs.createReadStream(pathFile); - await alfrescoJsApi.upload.uploadFile( - file, - '', - folderNode.entry.id, - null, - { - 'name': `e2e-result-${suffixFileName}-${retryCount}.tar`, - 'nodeType': 'cm:content', - 'autoRename': true - } - ); + const pathFile = path.join(__dirname, `../../e2e-result-${suffixFileName}-${retryCount}.tar`); + const file = fs.createReadStream(pathFile); + + await uploadApi.uploadFile(file, '', folderNode.entry.id, null, { + name: `e2e-result-${suffixFileName}-${retryCount}.tar`, + nodeType: 'cm:content', + autoRename: true + }); } module.exports = { diff --git a/lib/cli/scripts/check-cs-env.ts b/lib/cli/scripts/check-cs-env.ts index 59ab64525be..cc54849d7f3 100755 --- a/lib/cli/scripts/check-cs-env.ts +++ b/lib/cli/scripts/check-cs-env.ts @@ -1,16 +1,31 @@ -/* eslint-disable */ -const alfrescoApi = require('@alfresco/js-api'); +/*! + * @license + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AlfrescoApi, NodesApi, UploadApi } from '@alfresco/js-api'; +import { argv, exit } from 'node:process'; +import { Buffer } from 'node:buffer'; const program = require('commander'); -const path = require('path'); -const fs = require('fs'); -/* eslint-enable */ import { logger } from './logger'; const MAX_RETRY = 3; const TIMEOUT = 20000; let counter = 0; +let alfrescoJsApi: AlfrescoApi; export default async function main(_args: string[]) { - program .version('0.1.0') .description('Check Content service is up ') @@ -20,24 +35,26 @@ export default async function main(_args: string[]) { .option('-u, --username [type]', 'username ') .option('-t, --time [type]', 'time ') .option('-r, --retry [type]', 'retry ') - .parse(process.argv); + .parse(argv); await checkEnv(); - await checkDiskSpaceFullEnv(); + // TODO: https://alfresco.atlassian.net/browse/ACS-5873 + // await checkDiskSpaceFullEnv(); } async function checkEnv() { try { - const alfrescoJsApi = new alfrescoApi.AlfrescoApiCompatibility({ + alfrescoJsApi = new AlfrescoApi({ provider: 'ECM', - hostEcm: program.host + hostEcm: program.host, + contextRoot: 'alfresco' }); await alfrescoJsApi.login(program.username, program.password); } catch (error) { if (error?.error?.code === 'ETIMEDOUT') { logger.error('The env is not reachable. Terminating'); - process.exit(1); + exit(1); } logger.error('Login error environment down or inaccessible'); counter++; @@ -45,63 +62,33 @@ async function checkEnv() { const time = program.time || TIMEOUT; if (retry === counter) { logger.error('Give up'); - process.exit(1); + exit(1); } else { logger.error(`Retry in 1 minute attempt N ${counter}`, error); sleep(time); - checkEnv(); + await checkEnv(); } } } +// @ts-ignore async function checkDiskSpaceFullEnv() { logger.info(`Start Check disk full space`); try { + const nodesApi = new NodesApi(alfrescoJsApi); + const uploadApi = new UploadApi(alfrescoJsApi); - const alfrescoJsApi = new alfrescoApi.AlfrescoApiCompatibility({ - provider: 'ECM', - hostEcm: program.host - }); - - await alfrescoJsApi.login(program.username, program.password); - - let folder; - - try { - folder = await alfrescoJsApi.nodes.addNode('-my-', { - name: `try-env`, - relativePath: `Builds`, - nodeType: 'cm:folder' - }, {}, { - overwrite: true - }); + const fileContent = 'x'.repeat(1024 * 1024); + const file = Buffer.from(fileContent, 'utf8'); - } catch (error) { - folder = await alfrescoJsApi.nodes.getNode('-my-', { - relativePath: `Builds/try-env`, - nodeType: 'cm:folder' - }, {}, { - overwrite: true - }); - } - const pathFile = path.join(__dirname, '../', 'README.md'); - - const file = fs.createReadStream(pathFile); - - const uploadedFile = await alfrescoJsApi.upload.uploadFile( - file, - '', - folder.entry.id, - null, - { - name: 'README.md', - nodeType: 'cm:content', - autoRename: true - } - ); + const uploadedFile = await uploadApi.uploadFile(file, '', '-my-', null, { + name: 'README.md', + nodeType: 'cm:content', + autoRename: true + }); - alfrescoJsApi.node.deleteNode(uploadedFile.entry.id, {permanent: true}); + await nodesApi.deleteNode(uploadedFile.entry.id, { permanent: true }); } catch (error) { counter++; @@ -112,18 +99,17 @@ async function checkDiskSpaceFullEnv() { logger.info('================ Not able to upload a file =================='); logger.info('================ Possible cause CS is full =================='); logger.info('============================================================='); - process.exit(1); + exit(1); } else { - logger.error(`Retry N ${counter} ${error?.error?.status}`); + logger.error(`Retry N ${counter}`); + logger.error(JSON.stringify(error)); sleep(time); - checkDiskSpaceFullEnv(); + await checkDiskSpaceFullEnv(); } - } - } -function sleep(delay) { +function sleep(delay: number) { const start = new Date().getTime(); - while (new Date().getTime() < start + delay) { } + while (new Date().getTime() < start + delay) {} } diff --git a/lib/cli/scripts/check-ps-env.ts b/lib/cli/scripts/check-ps-env.ts index c7295a4a053..5c5d0a1a36c 100755 --- a/lib/cli/scripts/check-ps-env.ts +++ b/lib/cli/scripts/check-ps-env.ts @@ -1,14 +1,29 @@ -/* eslint-disable */ -const alfrescoApi = require('@alfresco/js-api'); +/*! + * @license + * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AlfrescoApi } from '@alfresco/js-api'; +import { exit, argv } from 'node:process'; const program = require('commander'); -/* eslint-enable */ import { logger } from './logger'; const MAX_RETRY = 10; const TIMEOUT = 60000; let counter = 0; export default async function main(_args: string[]) { - program .version('0.1.0') .description('Check Process service is up ') @@ -16,38 +31,39 @@ export default async function main(_args: string[]) { .option('--host [type]', 'Remote environment host adf.lab.com ') .option('-p, --password [type]', 'password ') .option('-u, --username [type]', 'username ') - .parse(process.argv); + .parse(argv); await checkEnv(); } async function checkEnv() { try { - const alfrescoJsApi = new alfrescoApi.AlfrescoApiCompatibility({ + const alfrescoJsApi = new AlfrescoApi({ provider: 'BPM', - hostBpm: program.host + hostBpm: program.host, + contextRoot: 'alfresco' }); await alfrescoJsApi.login(program.username, program.password); } catch (e) { if (e.error.code === 'ETIMEDOUT') { logger.error('The env is not reachable. Terminating'); - process.exit(1); + exit(1); } logger.error('Login error environment down or inaccessible'); counter++; if (MAX_RETRY === counter) { logger.error('Give up'); - process.exit(1); + exit(1); } else { logger.error(`Retry in 1 minute attempt N ${counter}`); sleep(TIMEOUT); - checkEnv(); + await checkEnv(); } } } -function sleep(delay) { +function sleep(delay: number) { const start = new Date().getTime(); - while (new Date().getTime() < start + delay) { } + while (new Date().getTime() < start + delay) {} } diff --git a/lib/cli/scripts/init-aae-env.ts b/lib/cli/scripts/init-aae-env.ts index b5daabdce10..c3d2c187b0d 100755 --- a/lib/cli/scripts/init-aae-env.ts +++ b/lib/cli/scripts/init-aae-env.ts @@ -22,14 +22,15 @@ import request = require('request'); import * as fs from 'fs'; import { logger } from './logger'; import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api'; +import { argv, exit } from 'node:process'; const ACTIVITI_CLOUD_APPS = require('./resources').ACTIVITI_CLOUD_APPS; -let alfrescoJsApiModeler: any; -let alfrescoJsApiDevops: any; +let alfrescoJsApiModeler: AlfrescoApi; +let alfrescoJsApiDevops: AlfrescoApi; let args: ConfigArgs; let isValid = true; -const absentApps: any [] = []; -const failingApps: any [] = []; +const absentApps: any[] = []; +const failingApps: any[] = []; export interface ConfigArgs { modelerUsername: string; modelerPassword: string; @@ -45,11 +46,7 @@ export interface ConfigArgs { envs: string[]; } -export const AAE_MICROSERVICES = [ - 'deployment-service', - 'modeling-service', - 'dmn-service' -]; +export const AAE_MICROSERVICES = ['deployment-service', 'modeling-service', 'dmn-service']; async function healthCheck(nameService: string) { const url = `${args.host}/${nameService}/actuator/health`; @@ -63,8 +60,17 @@ async function healthCheck(nameService: string) { const accepts = ['application/json']; try { - const health = await alfrescoJsApiModeler.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); + const health = await alfrescoJsApiModeler.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); if (health.status !== 'UP') { logger.error(`${nameService} is DOWN `); isValid = false; @@ -93,11 +99,21 @@ async function getApplicationByStatus(status: string) { try { await alfrescoJsApiDevops.login(args.devopsUsername, args.devopsPassword); - return alfrescoJsApiDevops.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts).on('error', (error) => { + const result = alfrescoJsApiDevops.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); + result.on('error', (error) => { logger.error(`Get application by status ${error} `); }); - + return result; } catch (error) { logger.error(`Get application by status ${error.status} `); isValid = false; @@ -116,9 +132,17 @@ function getDescriptors() { const accepts = ['application/json']; try { - return alfrescoJsApiDevops.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiDevops.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { logger.error(`Get Descriptors ${error.status} `); isValid = false; @@ -137,9 +161,17 @@ function getProjects() { const accepts = ['application/json']; try { - return alfrescoJsApiModeler.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiModeler.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { logger.error('Get Projects' + error.status); isValid = false; @@ -158,9 +190,17 @@ function getProjectRelease(projectId: string) { const accepts = ['application/json']; try { - return alfrescoJsApiModeler.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiModeler.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { logger.error('Get Projects Release' + error.status); isValid = false; @@ -179,9 +219,17 @@ async function releaseProject(projectId: string) { const accepts = ['application/json']; try { - return alfrescoJsApiModeler.oauth2Auth.callCustomApi(url, 'POST', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiModeler.oauth2Auth.callCustomApi( + url, + 'POST', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { await deleteProject(projectId); logger.error('Post Projects Release' + error.status); @@ -201,9 +249,17 @@ function deleteProject(projectId: string) { const accepts = ['application/json']; try { - return alfrescoJsApiModeler.oauth2Auth.callCustomApi(url, 'DELETE', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiModeler.oauth2Auth.callCustomApi( + url, + 'DELETE', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { logger.error('Delete project error' + error.status); isValid = false; @@ -211,20 +267,38 @@ function deleteProject(projectId: string) { } async function importAndReleaseProject(absoluteFilePath: string) { - const fileContent = await fs.createReadStream(absoluteFilePath); + const fileContent = fs.createReadStream(absoluteFilePath); try { - const project = await alfrescoJsApiModeler.oauth2Auth.callCustomApi(`${args.host}/modeling-service/v1/projects/import`, 'POST', {}, {}, {}, { file: fileContent }, {}, ['multipart/form-data'], ['application/json']); + const project = await alfrescoJsApiModeler.oauth2Auth.callCustomApi( + `${args.host}/modeling-service/v1/projects/import`, + 'POST', + {}, + {}, + {}, + { file: fileContent }, + {}, + ['multipart/form-data'], + ['application/json'] + ); logger.info(`Project imported`); logger.info(`Create release`); - const release = await alfrescoJsApiModeler.oauth2Auth.callCustomApi(`${args.host}/modeling-service/v1/projects/${project.entry.id}/releases`, 'POST', {}, {}, {}, {}, {}, - ['application/json'], ['application/json']); - return release; + return await alfrescoJsApiModeler.oauth2Auth.callCustomApi( + `${args.host}/modeling-service/v1/projects/${project.entry.id}/releases`, + 'POST', + {}, + {}, + {}, + {}, + {}, + ['application/json'], + ['application/json'] + ); } catch (error) { logger.error(`Not able to import the project/create the release ${absoluteFilePath} with status: ${error}`); isValid = false; - throw(error); + throw error; } } @@ -240,9 +314,17 @@ function deleteDescriptor(name: string) { const accepts = ['application/json']; try { - return alfrescoJsApiDevops.oauth2Auth.callCustomApi(url, 'DELETE', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiDevops.oauth2Auth.callCustomApi( + url, + 'DELETE', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { logger.error('Delete descriptor' + error.status); isValid = false; @@ -261,9 +343,17 @@ function deploy(model: any) { const accepts = ['application/json']; try { - return alfrescoJsApiDevops.oauth2Auth.callCustomApi(url, 'POST', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - + return alfrescoJsApiDevops.oauth2Auth.callCustomApi( + url, + 'POST', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { logger.error('Deploy post' + error.status); isValid = false; @@ -275,15 +365,16 @@ function initializeDefaultToken(options) { return options; } -function getAlfrescoJsApiInstance(configArgs: ConfigArgs) { +function getAlfrescoJsApiInstance(configArgs: ConfigArgs): AlfrescoApi { let ssoHost = configArgs.oauth; - ssoHost = ssoHost ?? configArgs.host; + ssoHost = ssoHost ?? configArgs.host; - const config = { + const config: AlfrescoApiConfig = { provider: 'BPM', hostBpm: `${configArgs.host}`, authType: 'OAUTH', - oauth2 : { + contextRoot: 'alfresco', + oauth2: { host: `${ssoHost}`, tokenUrl: `${ssoHost}/${configArgs.tokenEndpoint}`, clientId: `${configArgs.clientId}`, @@ -294,7 +385,7 @@ function getAlfrescoJsApiInstance(configArgs: ConfigArgs) { redirectUri: '/' } }; - return new AlfrescoApi(config as unknown as AlfrescoApiConfig); + return new AlfrescoApi(config); } async function deployMissingApps(tag?: string, envs?: string[]) { @@ -303,13 +394,13 @@ async function deployMissingApps(tag?: string, envs?: string[]) { findFailingApps(deployedApps.list.entries); if (failingApps.length > 0) { - failingApps.forEach( app => { + failingApps.forEach((app) => { const reset = '\x1b[0m'; const bright = '\x1b[1m'; const red = '\x1b[31m'; logger.error(`${red}${bright}ERROR: App ${app.entry.name} down or inaccessible ${reset}${red} with status ${app.entry.status}${reset}`); }); - process.exit(1); + exit(1); } else if (absentApps.length > 0) { logger.warn(`Missing apps: ${JSON.stringify(absentApps)}`); await checkIfAppIsReleased(absentApps, tag, envs); @@ -320,7 +411,7 @@ async function deployMissingApps(tag?: string, envs?: string[]) { } } -async function checkIfAppIsReleased(missingApps: any [], tag?: string, envs?: string[]) { +async function checkIfAppIsReleased(missingApps: any[], tag?: string, envs?: string[]) { const projectList = await getProjects(); let TIME = 5000; let noError = true; @@ -332,7 +423,6 @@ async function checkIfAppIsReleased(missingApps: any [], tag?: string, envs?: st let projectRelease: any; if (project === undefined) { - logger.warn('Missing project: Create the project for ' + currentAbsentApp.name); try { @@ -342,15 +432,13 @@ async function checkIfAppIsReleased(missingApps: any [], tag?: string, envs?: st if (error.status !== 409) { logger.info(`Not possible to upload the project ${currentAbsentApp.name} status : ${JSON.stringify(error)}`); - process.exit(1); + exit(1); } else { logger.error(`Not possible to upload the project because inconsistency CS - Modelling try to delete manually the node`); - process.exit(1); + exit(1); } } - } else { - TIME += 5000; logger.info('Project ' + project.entry.name + ' found'); @@ -380,7 +468,7 @@ async function checkIfAppIsReleased(missingApps: any [], tag?: string, envs?: st await sleep(TIME); if (envs && envs.length > 0) { - for (const envId of envs){ + for (const envId of envs) { await deployWithPayload(currentAbsentApp, projectRelease, envId); } } else { @@ -400,13 +488,12 @@ async function deployWithPayload(currentAbsentApp: any, projectRelease: any, env environmentId: envId }; - logger.info(`Deploying ${currentAbsentApp.name} ${envId ? 'on env: ' + envId : '' }`); + logger.info(`Deploying ${currentAbsentApp.name} ${envId ? 'on env: ' + envId : ''}`); await deploy(deployPayload); - logger.info(`Deployed ${currentAbsentApp.name} ${envId ? 'on env: ' + envId : '' }`); - + logger.info(`Deployed ${currentAbsentApp.name} ${envId ? 'on env: ' + envId : ''}`); } -async function checkDescriptorExist(name: string) { +async function checkDescriptorExist(name: string): Promise { logger.info(`Check descriptor ${name} exist in the list `); const descriptorList = await getDescriptors(); @@ -432,7 +519,7 @@ async function importProjectAndRelease(app: any, tag?: string) { return projectRelease; } -function findMissingApps(deployedApps: any []) { +function findMissingApps(deployedApps: any[]) { Object.keys(ACTIVITI_CLOUD_APPS).forEach((key) => { const isPresent = deployedApps.find((currentApp: any) => ACTIVITI_CLOUD_APPS[key].name === currentApp.entry.name); @@ -442,9 +529,11 @@ function findMissingApps(deployedApps: any []) { }); } -function findFailingApps(deployedApps: any []) { +function findFailingApps(deployedApps: any[]) { Object.keys(ACTIVITI_CLOUD_APPS).forEach((key) => { - const failingApp = deployedApps.filter((currentApp: any) => ACTIVITI_CLOUD_APPS[key].name === currentApp.entry.name && 'Running' !== currentApp.entry.status); + const failingApp = deployedApps.filter( + (currentApp: any) => ACTIVITI_CLOUD_APPS[key].name === currentApp.entry.name && 'Running' !== currentApp.entry.status + ); if (failingApp?.length > 0) { failingApps.push(...failingApp); @@ -474,20 +563,23 @@ async function deleteLocalFile(name: string) { async function sleep(time: number) { logger.info(`Waiting for ${time} sec...`); - await new Promise(done => setTimeout(done, time)); + await new Promise((done) => setTimeout(done, time)); logger.info(`Done...`); return; } -export default async function() { +// eslint-disable-next-line space-before-function-paren +export default async function () { await main(); } async function main() { program .version('0.1.0') - .description('The following command is in charge of Initializing the activiti cloud env with the default apps' + - 'adf-cli init-aae-env --host "gateway_env" --modelerUsername "modelerusername" --modelerPassword "modelerpassword" --devopsUsername "devevopsusername" --devopsPassword "devopspassword"') + .description( + 'The following command is in charge of Initializing the activiti cloud env with the default apps' + + 'adf-cli init-aae-env --host "gateway_env" --modelerUsername "modelerusername" --modelerPassword "modelerpassword" --devopsUsername "devevopsusername" --devopsPassword "devopspassword"' + ) .option('-h, --host [type]', 'Host gateway') .option('--oauth [type]', 'SSO host') .option('--clientId [type]', 'sso client') @@ -500,9 +592,9 @@ async function main() { .option('--devopsPassword [type]', 'devops password') .option('--tag [type]', 'tag name of the codebase') .option('--envs [type...]', 'environment ids of the envs where to deploy the app') - .parse(process.argv); + .parse(argv); - if (process.argv.includes('-h') || process.argv.includes('--help')) { + if (argv.includes('-h') || argv.includes('--help')) { program.outputHelp(); return; } @@ -519,7 +611,7 @@ async function main() { oauth: options.oauth, tokenEndpoint: options.tokenEndpoint, scope: options.scope, - secret: options.secret, + secret: options.secret, tag: options.tag, envs: options.envs }; @@ -530,31 +622,36 @@ async function main() { await healthCheck(serviceName); }); - await alfrescoJsApiModeler.login(args.modelerUsername, args.modelerPassword).then(() => { - const reset = '\x1b[0m'; - const green = '\x1b[32m'; - logger.info(`${green}login SSO ok${reset}`); - }, (error) => { - logger.error(`login SSO error ${JSON.stringify(error)} ${args.modelerUsername}`); - process.exit(1); - }); + await alfrescoJsApiModeler.login(args.modelerUsername, args.modelerPassword).then( + () => { + const reset = '\x1b[0m'; + const green = '\x1b[32m'; + logger.info(`${green}login SSO ok${reset}`); + }, + (error) => { + logger.error(`login SSO error ${JSON.stringify(error)} ${args.modelerUsername}`); + exit(1); + } + ); if (isValid) { const reset = '\x1b[0m'; const green = '\x1b[32m'; logger.info(`${green}The environment is up and running ${reset}`); alfrescoJsApiDevops = getAlfrescoJsApiInstance(args); - await alfrescoJsApiDevops.login(args.devopsUsername, args.devopsPassword).then(() => { - logger.info('login SSO ok devopsUsername'); - }, (error) => { - logger.error(`login SSO error ${JSON.stringify(error)} ${args.devopsUsername}`); - process.exit(1); - }); + await alfrescoJsApiDevops.login(args.devopsUsername, args.devopsPassword).then( + () => { + logger.info('login SSO ok devopsUsername'); + }, + (error) => { + logger.error(`login SSO error ${JSON.stringify(error)} ${args.devopsUsername}`); + exit(1); + } + ); await deployMissingApps(args.tag, args.envs); } else { logger.error('The environment is not up'); - process.exit(1); + exit(1); } - } diff --git a/lib/cli/scripts/init-acs-env.ts b/lib/cli/scripts/init-acs-env.ts index 809049a5367..572ad3941fa 100755 --- a/lib/cli/scripts/init-acs-env.ts +++ b/lib/cli/scripts/init-acs-env.ts @@ -15,39 +15,37 @@ * limitations under the License. */ -const alfrescoApi = require('@alfresco/js-api'); +import { AlfrescoApi, SharedlinksApi, FavoritesApi, NodesApi, UploadApi, NodeEntry } from '@alfresco/js-api'; +import { exit, argv } from 'node:process'; const program = require('commander'); -const fs = require ('fs'); +const fs = require('fs'); const path = require('path'); import { logger } from './logger'; -// eslint-disable-next-line @typescript-eslint/naming-convention -const { SharedlinksApi, FavoritesApi, NodesApi } = require('@alfresco/js-api'); const MAX_RETRY = 10; let counter = 0; const TIMEOUT = 6000; const ACS_DEFAULT = require('./resources').ACS_DEFAULT; -let alfrescoJsApi; +let alfrescoJsApi: AlfrescoApi; -export default async function() { +// eslint-disable-next-line space-before-function-paren +export default async function () { await main(); } async function main() { - program .version('0.1.0') .option('--host [type]', 'Remote environment host') .option('--clientId [type]', 'sso client', 'alfresco') .option('-p, --password [type]', 'password ') .option('-u, --username [type]', 'username ') - .parse(process.argv); + .parse(argv); await checkEnv(); logger.info(`***** Step initialize ACS *****`); await initializeDefaultFiles(); - } async function initializeDefaultFiles() { @@ -81,41 +79,35 @@ async function initializeDefaultFiles() { } async function createFolder(folderName: string, parentId: string) { - let createdFolder: any; - const body = { - name: folderName, - nodeType: 'cm:folder' - }; - try { - createdFolder = await new NodesApi(alfrescoJsApi).createNode(parentId, body, {overwrite: true}); - - logger.info(`Folder ${folderName} was created`); - } catch (err) { - if (err.status === 409) { - const relativePath = `/${folderName}`; - createdFolder = await new NodesApi(alfrescoJsApi).getNode('-my-', { relativePath }); - } + let createdFolder: NodeEntry; + const body = { + name: folderName, + nodeType: 'cm:folder' + }; + try { + createdFolder = await new NodesApi(alfrescoJsApi).createNode(parentId, body, { overwrite: true }); + + logger.info(`Folder ${folderName} was created`); + } catch (err) { + if (err.status === 409) { + const relativePath = `/${folderName}`; + createdFolder = await new NodesApi(alfrescoJsApi).getNode('-my-', { relativePath }); } - return createdFolder; + } + return createdFolder; } -async function uploadFile(fileName: string, fileDestination: string) { +async function uploadFile(fileName: string, fileDestination: string): Promise { const filePath = `../resources/content/${fileName}`; const file = fs.createReadStream(path.join(__dirname, filePath)); - let uploadedFile: any; + let uploadedFile: NodeEntry; try { - uploadedFile = await alfrescoJsApi.upload.uploadFile( - file, - '', - fileDestination, - null, - { - name: fileName, - nodeType: 'cm:content', - renditions: 'doclib', - overwrite: true - } - ); + uploadedFile = await new UploadApi(alfrescoJsApi).uploadFile(file, '', fileDestination, null, { + name: fileName, + nodeType: 'cm:content', + renditions: 'doclib', + overwrite: true + }); logger.info(`File ${fileName} was uploaded`); } catch (err) { logger.error(`Failed to upload file with error: `, err.stack); @@ -123,36 +115,37 @@ async function uploadFile(fileName: string, fileDestination: string) { return uploadedFile; } -async function lockFile(nodeId) { +async function lockFile(nodeId: string): Promise { const data = { type: 'ALLOW_OWNER_CHANGES' }; try { - await alfrescoJsApi.nodes.lockNode(nodeId, data); + const result = new NodesApi(alfrescoJsApi).lockNode(nodeId, data); logger.info('File was locked'); - } catch (error) { + return result; + } catch (error) { logger.error('Failed to lock file with error: ', error.stack); } } -async function shareFile(nodeId) { +async function shareFile(nodeId: string) { const data = { nodeId }; try { await new SharedlinksApi(alfrescoJsApi).createSharedLink(data); logger.info('File was shared'); - } catch (error) { + } catch (error) { logger.error('Failed to share file with error: ', error.stack); } } -async function favoriteFile(nodeId) { +async function favoriteFile(nodeId: string) { const data = { target: { - ['file']: { - guid: nodeId - } + ['file']: { + guid: nodeId + } } }; try { @@ -165,8 +158,7 @@ async function favoriteFile(nodeId) { async function checkEnv() { try { - - alfrescoJsApi = new alfrescoApi.AlfrescoApiCompatibility({ + alfrescoJsApi = new AlfrescoApi({ provider: 'ALL', hostBpm: program.host, hostEcm: program.host, @@ -174,31 +166,33 @@ async function checkEnv() { oauth2: { host: `${program.host}/auth/realms/alfresco`, clientId: `${program.clientId}`, - scope: 'openid' - } + scope: 'openid', + redirectUri: '/' + }, + contextRoot: 'alfresco' }); await alfrescoJsApi.login(program.username, program.password); } catch (e) { if (e.error.code === 'ETIMEDOUT') { logger.error('The env is not reachable. Terminating'); - process.exit(1); + exit(1); } logger.error('Login error environment down or inaccessible'); counter++; if (MAX_RETRY === counter) { logger.error('Give up'); - process.exit(1); + exit(1); } else { logger.error(`Retry in 1 minute attempt N ${counter}`); sleep(TIMEOUT); - checkEnv(); + await checkEnv(); } } } /* eslint-enable */ -function sleep(delay) { +function sleep(delay: number) { const start = new Date().getTime(); - while (new Date().getTime() < start + delay) { } + while (new Date().getTime() < start + delay) {} } diff --git a/lib/cli/scripts/init-aps-env.ts b/lib/cli/scripts/init-aps-env.ts index b492e1154cd..9ab2d44a3a3 100755 --- a/lib/cli/scripts/init-aps-env.ts +++ b/lib/cli/scripts/init-aps-env.ts @@ -15,14 +15,14 @@ * limitations under the License. */ -const alfrescoApi = require('@alfresco/js-api'); +import { AdminTenantsApi, AdminUsersApi, AlfrescoApi, TenantRepresentation, AppDefinitionsApi, RuntimeAppDefinitionsApi, UserRepresentation } from '@alfresco/js-api'; +import { argv, exit } from 'node:process'; +import { spawnSync } from 'node:child_process'; +import { createReadStream } from 'node:fs'; const program = require('commander'); -const fs = require ('fs'); const path = require('path'); import { logger } from './logger'; const { throwError } = require('rxjs'); -// eslint-disable-next-line @typescript-eslint/naming-convention -const { AppDefinitionsApi, RuntimeAppDefinitionsApi } = require('@alfresco/js-api'); const MAX_RETRY = 10; let counter = 0; const TIMEOUT = 6000; @@ -31,8 +31,7 @@ const TENANT_DEFAULT_NAME = 'default'; const CONTENT_DEFAULT_NAME = 'adw-content'; const ACTIVITI_APPS = require('./resources').ACTIVITI_APPS; -let alfrescoJsApi; -let alfrescoJsApiRepo; +let alfrescoJsApi: AlfrescoApi; export default async function() { await main(); @@ -47,7 +46,7 @@ async function main() { .option('-p, --password [type]', 'password ') .option('-u, --username [type]', 'username ') .option('--license [type]', 'APS license S3 path ') - .parse(process.argv); + .parse(argv); await checkEnv(); @@ -68,16 +67,16 @@ async function main() { let tenantId; if (licenceUploaded) { logger.info(`***** Step 2 - Check Tenant *****`); - logger.info(`is tenandId:${TENANT_DEFAULT_ID} with name:${TENANT_DEFAULT_NAME} present?`); + logger.info(`is tenantId:${TENANT_DEFAULT_ID} with name:${TENANT_DEFAULT_NAME} present?`); try { const hasDefault = await hasDefaultTenant(TENANT_DEFAULT_ID, TENANT_DEFAULT_NAME); tenantId = TENANT_DEFAULT_ID; if (!hasDefault) { - // the tenandId should be equal to TENANT_DEFAULT_ID if we choose 1 as id. + // the tenantId should be equal to TENANT_DEFAULT_ID if we choose 1 as id. tenantId = await createDefaultTenant(TENANT_DEFAULT_NAME); } logger.info(`***** Step 3 - Add Content Repo *****`); - const isContentPresent = await isContenRepoPresent(TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME); + const isContentPresent = await isContentRepoPresent(TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME); if (!isContentPresent) { logger.info(`No content repo with name ${CONTENT_DEFAULT_NAME} found`); await addContentRepoWithBasic(TENANT_DEFAULT_ID, CONTENT_DEFAULT_NAME); @@ -90,7 +89,7 @@ async function main() { } for (let i = 0; i < users.length; i++) { logger.info('Impersonate user: ' + users[i].username); - await alfrescoJsApiRepo.login(users[i].username, 'password'); + await alfrescoJsApi.login(users[i].username, 'password'); await authorizeUserToContentRepo(users[i]); const defaultUser = 'hruser'; @@ -106,11 +105,11 @@ async function main() { } catch (error) { logger.info(`Aps something went wrong. Tenant id ${tenantId}`); - process.exit(1); + exit(1); } } else { logger.info('APS license error: check the configuration'); - process.exit(1); + exit(1); } } @@ -129,47 +128,49 @@ async function initializeDefaultApps() { } async function checkEnv() { try { - - alfrescoJsApi = new alfrescoApi.AlfrescoApiCompatibility({ + alfrescoJsApi = new AlfrescoApi({ provider: 'ALL', hostBpm: program.host, hostEcm: program.host, authType: 'OAUTH', + contextRoot: 'alfresco', oauth2: { host: `${program.host}/auth/realms/alfresco`, clientId: `${program.clientId}`, - scope: 'openid' + scope: 'openid', + redirectUri: '/' } }); - alfrescoJsApiRepo = alfrescoJsApi; await alfrescoJsApi.login(program.username, program.password); } catch (e) { if (e.error.code === 'ETIMEDOUT') { logger.error('The env is not reachable. Terminating'); - process.exit(1); + exit(1); } logger.info('Login error environment down or inaccessible'); counter++; if (MAX_RETRY === counter) { logger.error('Give up'); - process.exit(1); + exit(1); } else { logger.error(`Retry in 1 minute attempt N ${counter}`); sleep(TIMEOUT); - checkEnv(); + await checkEnv(); } } } -async function hasDefaultTenant(tenantId, tenantName) { - let tenant; +async function hasDefaultTenant(tenantId: number, tenantName: string) { + let tenant: TenantRepresentation; try { - tenant = await alfrescoJsApi.activiti.adminTenantsApi.getTenant(tenantId); + const adminTenantsApi = new AdminTenantsApi(alfrescoJsApi); + tenant = await adminTenantsApi.getTenant(tenantId); } catch (error) { logger.info(`Aps: does not have tenant with id: ${tenantId}`); return false; } + if (tenant.name === tenantName) { logger.info(`Aps: has default tenantId: ${tenantId} and name ${tenantName}`); return true; @@ -179,7 +180,7 @@ async function hasDefaultTenant(tenantId, tenantName) { } } -async function createDefaultTenant(tenantName) { +async function createDefaultTenant(tenantName: string) { const tenantPost = { active: true, maxUsers: 10000, @@ -187,7 +188,8 @@ async function createDefaultTenant(tenantName) { }; try { - const tenant = await alfrescoJsApi.activiti.adminTenantsApi.createTenant(tenantPost); + const adminTenantsApi = new AdminTenantsApi(alfrescoJsApi); + const tenant = await adminTenantsApi.createTenant(tenantPost); logger.info(`APS: Tenant ${tenantName} created with id: ${tenant.id}`); return tenant.id; } catch (error) { @@ -195,21 +197,22 @@ async function createDefaultTenant(tenantName) { } } -async function createUsers(tenandId, user) { - logger.info(`Create user ${user.email} on tenant: ${tenandId}`); +async function createUsers(tenantId: number, user: any) { + logger.info(`Create user ${user.email} on tenant: ${tenantId}`); const passwordCamelCase = 'Password'; - const userJson = { + const userJson = new UserRepresentation({ email: user.email, firstName: user.firstName, lastName: user.lastName, status: 'active', type: 'enterprise', password: passwordCamelCase, - tenantId: tenandId - }; + tenantId + }); try { - const userInfo = await alfrescoJsApi.activiti.adminUsersApi.createNewUser(userJson); + const adminUsersApi = new AdminUsersApi(alfrescoJsApi); + const userInfo = await adminUsersApi.createNewUser(userJson); logger.info(`APS: User ${userInfo.email} created with id: ${userInfo.id}`); return user; } catch (error) { @@ -218,7 +221,7 @@ async function createUsers(tenandId, user) { } async function updateLicense() { - const fileContent = fs.createReadStream(path.join(__dirname, '/activiti.lic')); + const fileContent = createReadStream(path.join(__dirname, '/activiti.lic')); try { await alfrescoJsApi.oauth2Auth.callCustomApi( @@ -243,9 +246,9 @@ async function updateLicense() { async function isDefaultAppDeployed(appName: string) { logger.info(`Verify ${appName} already deployed`); try { - const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApiRepo); + const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApi); const availableApps = await runtimeAppDefinitionsApi.getAppDefinitions(); - const defaultApp = availableApps.data && availableApps.data.filter( app => app.name && app.name.includes(appName)); + const defaultApp = availableApps.data && availableApps.data.filter(app => app.name && app.name.includes(appName)); return defaultApp && defaultApp.length > 0; } catch (error) { logger.error(`Aps app failed to import/Publish!`); @@ -256,10 +259,10 @@ async function importPublishApp(appName: string) { const appNameExtension = `../resources/${appName}.zip`; logger.info(`Import app ${appNameExtension}`); const pathFile = path.join(__dirname, appNameExtension); - const fileContent = fs.createReadStream(pathFile); + const fileContent = createReadStream(pathFile); try { - const appdefinitionsApi = new AppDefinitionsApi(alfrescoJsApiRepo); + const appdefinitionsApi = new AppDefinitionsApi(alfrescoJsApi); const result = await appdefinitionsApi.importAndPublishApp(fileContent, {renewIdmEntries: true}); logger.info(`Aps app imported and published!`); return result; @@ -268,14 +271,14 @@ async function importPublishApp(appName: string) { } } -async function deployApp(appDefinitioId) { - logger.info(`Deploy app with id ${appDefinitioId}`); +async function deployApp(appDefinitionId: number) { + logger.info(`Deploy app with id ${appDefinitionId}`); const body = { - appDefinitions: [{id: appDefinitioId}] + appDefinitions: [{id: appDefinitionId}] }; try { - const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApiRepo); + const runtimeAppDefinitionsApi = new RuntimeAppDefinitionsApi(alfrescoJsApi); await runtimeAppDefinitionsApi.deployAppDefinitions(body); logger.info(`Aps app deployed`); } catch (error) { @@ -283,7 +286,7 @@ async function deployApp(appDefinitioId) { } } -async function hasLicense() { +async function hasLicense(): Promise { try { const license = await alfrescoJsApi.oauth2Auth.callCustomApi( `${program.host}/activiti-app/app/rest/license`, @@ -308,9 +311,8 @@ async function hasLicense() { } async function getDefaultApsUsersFromRealm() { - try { - const users = await alfrescoJsApi.oauth2Auth.callCustomApi( + const users: any[] = await alfrescoJsApi.oauth2Auth.callCustomApi( `${program.host}/auth/admin/realms/alfresco/users`, 'GET', {}, @@ -330,8 +332,7 @@ async function getDefaultApsUsersFromRealm() { } } -async function isContenRepoPresent(tenantId, contentName) { - +async function isContentRepoPresent(tenantId: number, contentName: string): Promise { try { const contentRepos = await alfrescoJsApi.oauth2Auth.callCustomApi( `${program.host}/activiti-app/app/rest/integration/alfresco?tenantId=${tenantId}`, @@ -350,8 +351,9 @@ async function isContenRepoPresent(tenantId, contentName) { } } -async function addContentRepoWithBasic(tenantId, name) { +async function addContentRepoWithBasic(tenantId: number, name: string) { logger.info(`Create Content with name ${name} and basic auth`); + const body = { alfrescoTenantId: '', authenticationType: 'basic', @@ -382,10 +384,10 @@ async function addContentRepoWithBasic(tenantId, name) { } } -async function authorizeUserToContentRepo(user) { +async function authorizeUserToContentRepo(user: any) { logger.info(`Authorize user ${user.email}`); try { - const content = await alfrescoJsApiRepo.oauth2Auth.callCustomApi( + const content = await alfrescoJsApi.oauth2Auth.callCustomApi( `${program.host}/activiti-app/app/rest/integration/alfresco`, 'GET', {}, @@ -410,11 +412,11 @@ async function authorizeUserToContentRepo(user) { } } -async function authorizeUserToContentWithBasic(username, contentId) { +async function authorizeUserToContentWithBasic(username: string, contentId: string) { logger.info(`Authorize ${username} on contentId: ${contentId} in basic auth`); try { const body = {username, password: 'password'}; - const content = await alfrescoJsApiRepo.oauth2Auth.callCustomApi( + const content = await alfrescoJsApi.oauth2Auth.callCustomApi( `${program.host}/activiti-app/app/rest/integration/alfresco/${contentId}/account`, 'POST', {}, @@ -432,13 +434,11 @@ async function authorizeUserToContentWithBasic(username, contentId) { } } -/* eslint-disable */ -async function downloadLicenseFile(apsLicensePath) { - +async function downloadLicenseFile(apsLicensePath: string) { try { - const child_process = require("child_process"); - child_process.execSync(` aws s3 cp ${apsLicensePath} ./ `, { - cwd: path.resolve(__dirname, `./`) + spawnSync(` aws s3 cp ${apsLicensePath} ./ `, { + cwd: path.resolve(__dirname, `./`), + shell: false }); logger.info(`Aps license file download from S3 bucket`); return true; @@ -447,9 +447,8 @@ async function downloadLicenseFile(apsLicensePath) { return false; } } -/* eslint-enable */ -function sleep(delay) { +function sleep(delay: number) { const start = new Date().getTime(); while (new Date().getTime() < start + delay) { } } diff --git a/lib/cli/scripts/kubectl-clean-app.ts b/lib/cli/scripts/kubectl-clean-app.ts index f5178ea1ef0..9d56eb9bd1e 100644 --- a/lib/cli/scripts/kubectl-clean-app.ts +++ b/lib/cli/scripts/kubectl-clean-app.ts @@ -17,6 +17,7 @@ * limitations under the License. */ +import { argv, exit } from 'node:process'; import program from 'commander'; import moment from 'moment'; import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api'; @@ -40,11 +41,12 @@ export interface ConfigArgs { intervalTime: string; } -function getAlfrescoJsApiInstance(args: ConfigArgs) { - const config = { +function getAlfrescoJsApiInstance(args: ConfigArgs): AlfrescoApi { + const config: AlfrescoApiConfig = { provider: 'BPM', hostBpm: `${args.host}`, authType: 'OAUTH', + contextRoot: 'alfresco', oauth2: { host: `${args.oauth}/auth/realms/alfresco`, clientId: `${args.clientId}`, @@ -55,21 +57,21 @@ function getAlfrescoJsApiInstance(args: ConfigArgs) { redirectUri: '/' } }; - return new AlfrescoApi(config as unknown as AlfrescoApiConfig); + return new AlfrescoApi(config); } -async function login(username: string, password: string, alfrescoJsApi: any) { +async function login(username: string, password: string, alfrescoJsApi: AlfrescoApi) { logger.info(`Perform login...`); try { - await alfrescoJsApi.login(username, password); + await alfrescoJsApi.login(username, password); } catch (error) { logger.error(`Not able to login. Credentials ${username}:${password} are not valid`); - process.exit(1); + exit(1); } logger.info(`Perform done...`); } -async function deleteDescriptor(args: ConfigArgs, apiService: any, name: string) { +async function deleteDescriptor(args: ConfigArgs, apiService: AlfrescoApi, name: string) { logger.warn(`Delete the descriptor ${name}`); const url = `${args.host}/deployment-service/v1/descriptors/${name}`; @@ -84,13 +86,25 @@ async function deleteDescriptor(args: ConfigArgs, apiService: any, name: string) const accepts = ['application/json']; try { - return await apiService.oauth2Auth.callCustomApi(url, 'DELETE', pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts); + return await apiService.oauth2Auth.callCustomApi( + url, + 'DELETE', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { - logger.error(`Not possible to delete the descriptor ${name} status : ${JSON.stringify(error.status)} ${JSON.stringify(error?.response?.text)}`); + logger.error( + `Not possible to delete the descriptor ${name} status: ${JSON.stringify(error.status)} ${JSON.stringify(error?.response?.text)}` + ); } } -async function deleteProject(args: ConfigArgs, apiService: any, projectId: string) { +async function deleteProject(args: ConfigArgs, apiService: AlfrescoApi, projectId: string) { logger.warn(`Delete the project ${projectId}`); const url = `${args.host}/modeling-service/v1/projects/${projectId}`; @@ -105,13 +119,25 @@ async function deleteProject(args: ConfigArgs, apiService: any, projectId: strin const accepts = ['application/json']; try { - return await apiService.oauth2Auth.callCustomApi(url, 'DELETE', pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts); + return await apiService.oauth2Auth.callCustomApi( + url, + 'DELETE', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { - logger.error(`Not possible to delete the project ${projectId} status : ${JSON.stringify(error.status)} ${JSON.stringify(error?.response?.text)}`); + logger.error( + `Not possible to delete the project ${projectId} status : ${JSON.stringify(error.status)} ${JSON.stringify(error?.response?.text)}` + ); } } -async function deleteProjectByName(args: ConfigArgs, apiService: any, name: string) { +async function deleteProjectByName(args: ConfigArgs, apiService: AlfrescoApi, name: string) { logger.warn(`Get the project by name ${name}`); const url = `${args.host}/modeling-service/v1/projects?name=${name}`; @@ -124,20 +150,29 @@ async function deleteProjectByName(args: ConfigArgs, apiService: any, name: stri const accepts = ['application/json']; try { - const data = await apiService.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); - for (let i = 0; i < data.list.entries.length; i++ ) { + const data = await apiService.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); + for (let i = 0; i < data.list.entries.length; i++) { if (data.list.entries[i].entry.name === name) { await deleteProject(args, apiService, data.list.entries[i].entry.id); } } } catch (error) { logger.error(`Not possible to get the project with name ${name} ` + JSON.stringify(error)); - process.exit(1); + exit(1); } } -async function getApplicationsByName(args: ConfigArgs, apiService: any, name: string) { +async function getApplicationsByName(args: ConfigArgs, apiService: AlfrescoApi, name: string) { logger.warn(`Get the applications by name ${name}`); const url = `${args.host}/deployment-service/v1/applications?name=${name}`; @@ -150,8 +185,17 @@ async function getApplicationsByName(args: ConfigArgs, apiService: any, name: st const accepts = ['application/json']; try { - const apps = await apiService.oauth2Auth.callCustomApi(url, 'GET', pathParams, queryParams, headerParams, formParams, bodyParam, - contentTypes, accepts); + const apps = await apiService.oauth2Auth.callCustomApi( + url, + 'GET', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); return apps ? apps.list.entries : []; } catch (error) { logger.error(`Not possible to get the applications with name ${name} ` + JSON.stringify(error)); @@ -159,7 +203,7 @@ async function getApplicationsByName(args: ConfigArgs, apiService: any, name: st } } -async function undeployApplication(args: ConfigArgs, apiService: any, name: string) { +async function undeployApplication(args: ConfigArgs, apiService: AlfrescoApi, name: string) { logger.warn(`Undeploy the application ${name}`); const url = `${args.host}/deployment-service/v1/applications/${name}`; @@ -174,22 +218,36 @@ async function undeployApplication(args: ConfigArgs, apiService: any, name: stri const accepts = ['application/json']; try { - return await apiService.oauth2Auth.callCustomApi(url, 'DELETE', pathParams, queryParams, headerParams, formParams, bodyParam, contentTypes, accepts); + return await apiService.oauth2Auth.callCustomApi( + url, + 'DELETE', + pathParams, + queryParams, + headerParams, + formParams, + bodyParam, + contentTypes, + accepts + ); } catch (error) { - logger.error(`Not possible to undeploy the applications ${name} status : ${JSON.stringify(error.status)} ${JSON.stringify(error?.response?.text)}`); + logger.error( + `Not possible to undeploy the applications ${name} status: ${JSON.stringify(error.status)} ${JSON.stringify(error?.response?.text)}` + ); } } -// eslint-disable-next-line prefer-arrow/prefer-arrow-functions -export default async function(args: ConfigArgs) { +// eslint-disable-next-line prefer-arrow/prefer-arrow-functions,space-before-function-paren +export default async function (args: ConfigArgs) { await main(args); } const main = async (args: ConfigArgs) => { program .version('0.1.0') - .description('The following command is in charge of cleaning the releases/application/descriptor related to an app passed as input' + - 'adf-cli kubectl-clean-app --host "gateway_env" --modelerUsername "modelerusername" --modelerPassword "modelerpassword" --oauth "identity_env" --username "username" --password "password"') + .description( + 'The following command is in charge of cleaning the releases/application/descriptor related to an app passed as input' + + 'adf-cli kubectl-clean-app --host "gateway_env" --modelerUsername "modelerusername" --modelerPassword "modelerpassword" --oauth "identity_env" --username "username" --password "password"' + ) .option('-h, --host [type]', 'Host gateway') .option('-o, --oauth [type]', 'Host sso server') .option('--clusterEnv [type]', 'cluster Envirorment') @@ -204,28 +262,34 @@ const main = async (args: ConfigArgs) => { .option('--apps [type]', 'Application prefix') .option('--enableLike [boolean]', 'Enable the like for app name') .option('--intervalTime [string]', 'In case of enableLike it specify the time related to the createDate') - .parse(process.argv); + .parse(argv); - if (process.argv.includes('-h') || process.argv.includes('--help')) { + if (argv.includes('-h') || argv.includes('--help')) { program.outputHelp(); return; } const alfrescoJsApiModeler = getAlfrescoJsApiInstance(args); - await login(args.modelerUsername, args.modelerPassword, alfrescoJsApiModeler).then(() => { - logger.info('login SSO ok'); - }, (error) => { - logger.info(`login SSO error ${JSON.stringify(error)}`); - process.exit(1); - }); + await login(args.modelerUsername, args.modelerPassword, alfrescoJsApiModeler).then( + () => { + logger.info('login SSO ok'); + }, + (error) => { + logger.info(`login SSO error ${JSON.stringify(error)}`); + exit(1); + } + ); const alfrescoJsApiDevops = getAlfrescoJsApiInstance(args); - await login(args.devopsUsername, args.devopsPassword, alfrescoJsApiDevops).then(() => { - logger.info('login SSO ok'); - }, (error) => { - logger.info(`login SSO error ${JSON.stringify(error)}`); - process.exit(1); - }); + await login(args.devopsUsername, args.devopsPassword, alfrescoJsApiDevops).then( + () => { + logger.info('login SSO ok'); + }, + (error) => { + logger.info(`login SSO error ${JSON.stringify(error)}`); + exit(1); + } + ); if (args.apps !== undefined) { kube.setCluster(args.clusterEnv, args.clusterUrl); @@ -238,13 +302,13 @@ const main = async (args: ConfigArgs) => { const extractTimeRange = parseInt(interval.split(' ')[0], 10); logger.info(`Extract time ${extractTimeRange} from interval: ${interval}`); - for (let i = 0; i < applications.length; i++ ) { + for (let i = 0; i < applications.length; i++) { logger.info(`Perform action on app: ${applications[i]}`); if (args.enableLike) { const applicationsByName = await getApplicationsByName(args, alfrescoJsApiDevops, applications[i]); logger.info(`Found ${applicationsByName.length} apps`); - for (let y = 0; y < applicationsByName.length; y++ ) { + for (let y = 0; y < applicationsByName.length; y++) { const application = applicationsByName[y].entry; logger.info(`Analyze app: ${application.name} `); const diffAsMinutes = moment.duration(moment().diff(moment(application.createdAt))).asMinutes(); diff --git a/lib/cli/scripts/plugins/check-env.ts b/lib/cli/scripts/plugins/check-env.ts index be0d6b14ddf..25ef7a39396 100644 --- a/lib/cli/scripts/plugins/check-env.ts +++ b/lib/cli/scripts/plugins/check-env.ts @@ -15,65 +15,61 @@ * limitations under the License. */ +import { AlfrescoApi } from '@alfresco/js-api'; +import { exit } from 'node:process'; import { logger } from './../logger'; -import alfrescoApi = require('@alfresco/js-api'); const TIMEOUT = 6000; const MAX_RETRY = 10; export class CheckEnv { - _alfrescoJsApi: any; + _alfrescoJsApi: AlfrescoApi; counter = 0; - constructor( - private host: string, - private username: string, - private password: string, - private clientId: string = 'alfresco' - ) {} + constructor(private host: string, private username: string, private password: string, private clientId: string = 'alfresco') {} async checkEnv() { try { - this.alfrescoJsApi = new alfrescoApi.AlfrescoApiCompatibility({ + this.alfrescoJsApi = new AlfrescoApi({ provider: 'ALL', hostBpm: this.host, hostEcm: this.host, authType: 'OAUTH', + contextRoot: 'alfresco', oauth2: { host: `${this.host}/auth/realms/alfresco`, clientId: `${this.clientId}`, - scope: 'openid' + scope: 'openid', + redirectUri: '/' } - } as any); + }); await this.alfrescoJsApi.login(this.username, this.password); } catch (e) { if (e.error.code === 'ETIMEDOUT') { logger.error('The env is not reachable. Terminating'); - process.exit(1); + exit(1); } logger.error('Login error environment down or inaccessible'); this.counter++; if (MAX_RETRY === this.counter) { logger.error('Give up'); - process.exit(1); + exit(1); } else { - logger.error( - `Retry in 1 minute at main();tempt N ${this.counter}` - ); + logger.error(`Retry in 1 minute at main();tempt N ${this.counter}`); this.sleep(TIMEOUT); - this.checkEnv(); + await this.checkEnv(); } } } - public get alfrescoJsApi() { + public get alfrescoJsApi(): AlfrescoApi { return this._alfrescoJsApi; } - public set alfrescoJsApi(alfrescoJsApi: any) { + public set alfrescoJsApi(alfrescoJsApi: AlfrescoApi) { this._alfrescoJsApi = alfrescoJsApi; } - sleep(delay) { + sleep(delay: number) { const start = new Date().getTime(); while (new Date().getTime() < start + delay) {} } diff --git a/lib/cli/scripts/plugins/governance-check-plugin.ts b/lib/cli/scripts/plugins/governance-check-plugin.ts index 9fa4bb393a3..208e2642941 100644 --- a/lib/cli/scripts/plugins/governance-check-plugin.ts +++ b/lib/cli/scripts/plugins/governance-check-plugin.ts @@ -17,13 +17,11 @@ import { PluginInterface } from './plugin-model'; import { GovernanceHealth } from './governance-health'; +import { AlfrescoApi } from '@alfresco/js-api'; export class GovernanceCheckPlugin { governanceHealth: GovernanceHealth; - constructor( - private pluginInfo: PluginInterface, - private alfrescoJsApi: any - ) { + constructor(private pluginInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) { this.governanceHealth = new GovernanceHealth(this.pluginInfo, this.alfrescoJsApi); } diff --git a/lib/cli/scripts/plugins/governance-health.ts b/lib/cli/scripts/plugins/governance-health.ts index 1df6ab2f4c0..8a3ad6edeb6 100644 --- a/lib/cli/scripts/plugins/governance-health.ts +++ b/lib/cli/scripts/plugins/governance-health.ts @@ -19,48 +19,38 @@ import { logger } from '../logger'; import { PluginInterface } from './plugin-model'; +import { AlfrescoApi, GsSitesApi } from '@alfresco/js-api'; export class GovernanceHealth { - constructor(private pluginInfo: PluginInterface, private alfrescoJsApi: any) {} + constructor(private pluginInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) {} - async isRecordManagementAvailable() { + async isRecordManagementAvailable(): Promise { try { - const site = await this.alfrescoJsApi.gsCore.gsSitesApi.getRMSite(); - logger.info( - `Record Management site is present: ${site.entry.title}` - ); + const gsSitesApi = new GsSitesApi(this.alfrescoJsApi); + const site = await gsSitesApi.getRMSite(); + logger.info(`Record Management site is present: ${site.entry.title}`); console.table([{ PluginName: this.pluginInfo.name, Status: 'Active', RecordManagement: 'Available' }]); return true; } catch (error) { - logger.error( - `Record Management site get failed: ${ - JSON.parse(error.message).error.errorKey - }` - ); - console.table([{ PluginName: this.pluginInfo.name, Status: 'Inactive', RecordManagement: 'Not available'}]); + logger.error(`Record Management site get failed: ${JSON.parse(error.message).error.errorKey}`); + console.table([{ PluginName: this.pluginInfo.name, Status: 'Inactive', RecordManagement: 'Not available' }]); return false; } } - async createRecordManagementSite() { + async createRecordManagementSite(): Promise { const body = { title: 'Records Management' }; const opts = { skipAddToFavorites: false }; // | Flag to indicate whether the RM site should not be added to the user's site favorites. try { logger.info('Trying to create Record Management site...'); - const site = await this.alfrescoJsApi.gsCore.gsSitesApi.createRMSite( - body, - opts - ); + const gsSitesApi = new GsSitesApi(this.alfrescoJsApi); + const site = await gsSitesApi.createRMSite(body, opts); logger.info('Record Management site: created' + site); - console.table([{ PluginName: this.pluginInfo.name, Status: 'Active', RecordManagement: 'Created'}]); + console.table([{ PluginName: this.pluginInfo.name, Status: 'Active', RecordManagement: 'Created' }]); } catch (error) { - logger.error( - `Record Management site creation failed: ${ - JSON.parse(error.message).error.errorKey - }` - ); - console.table([{ PluginName: this.pluginInfo.name, Status: 'Inactive', RecordManagement: 'Not created'}]); + logger.error(`Record Management site creation failed: ${JSON.parse(error.message).error.errorKey}`); + console.table([{ PluginName: this.pluginInfo.name, Status: 'Inactive', RecordManagement: 'Not created' }]); } } } diff --git a/lib/cli/scripts/plugins/plugin-config.ts b/lib/cli/scripts/plugins/plugin-config.ts index 97507ff27fa..693486e5a0d 100644 --- a/lib/cli/scripts/plugins/plugin-config.ts +++ b/lib/cli/scripts/plugins/plugin-config.ts @@ -17,12 +17,10 @@ import { PluginInterface } from './plugin-model'; import { logger } from '../logger'; +import { AlfrescoApi } from '@alfresco/js-api'; export class PluginConfiguration { - constructor( - private plugInInfo: PluginInterface, - private alfrescoJsApi: any - ) {} + constructor(private plugInInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) {} async getAppConfig(url: string) { return this.callCustomApi(url); @@ -52,10 +50,7 @@ export class PluginConfiguration { return response; } catch (error) { - logger.error( - `${this.plugInInfo.host} is not reachable error: `, - error - ); + logger.error(`${this.plugInInfo.host} is not reachable error: `, error); return {}; } } diff --git a/lib/cli/scripts/plugins/process-automation-check-plugin.ts b/lib/cli/scripts/plugins/process-automation-check-plugin.ts index eae05e0aefb..e9be9f375fe 100644 --- a/lib/cli/scripts/plugins/process-automation-check-plugin.ts +++ b/lib/cli/scripts/plugins/process-automation-check-plugin.ts @@ -20,55 +20,49 @@ import { PluginInterface } from './plugin-model'; import { logger } from '../logger'; import { ProcessAutomationHealth } from './process-automation-health'; +import { AlfrescoApi } from '@alfresco/js-api'; +import { exit } from 'node:process'; export class ProcessAutomationCheckPlugin { processAutomationHealth: ProcessAutomationHealth; - constructor( - private plugInInfo: PluginInterface, - private alfrescoJsApi: any - ) { - this.processAutomationHealth = new ProcessAutomationHealth( - this.plugInInfo, - this.alfrescoJsApi - ); + constructor(private plugInInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) { + this.processAutomationHealth = new ProcessAutomationHealth(this.plugInInfo, this.alfrescoJsApi); } - async checkProcessAutomationPlugin() { + async checkProcessAutomationPlugin(): Promise { let pluginStatus; try { const isPluginEnabled = await this.processAutomationHealth.isPluginEnabledFromAppConfiguration(); const isBackendActive = await this.processAutomationHealth.checkBackendHealth(); if (isPluginEnabled && isBackendActive) { - logger.info( - `The plugin ${ - this.plugInInfo.name - } has been correctly configured` - ); + logger.info(`The plugin ${this.plugInInfo.name} has been correctly configured`); pluginStatus = [{ PluginName: this.plugInInfo.name, Status: 'Active', BE: 'UP', FE: 'Enabled' }]; console.table(pluginStatus); } else { this.logConfigurationError(); - pluginStatus = [{ PluginName: this.plugInInfo.name, Status: 'Inactive', BE: isBackendActive ? 'UP' : 'DOWN', FE: isPluginEnabled ? 'Enabled' : 'Disabled' }]; + pluginStatus = [ + { + PluginName: this.plugInInfo.name, + Status: 'Inactive', + BE: isBackendActive ? 'UP' : 'DOWN', + FE: isPluginEnabled ? 'Enabled' : 'Disabled' + } + ]; console.table(pluginStatus); - process.exit(1); + exit(1); } } catch (e) { this.logConfigurationError(e); pluginStatus = [{ PluginName: this.plugInInfo.name, Status: 'Inactive', BE: 'DOWN', FE: 'Disabled' }]; console.table(pluginStatus); - process.exit(1); + exit(1); } } - private logConfigurationError(error?: any) { - logger.error( - `The plugin ${ - this.plugInInfo.name - } has not been correctly configured`, - error - ); + private logConfigurationError(error?: any): void { + logger.error(`The plugin ${this.plugInInfo.name} has not been correctly configured`, error); } } diff --git a/lib/cli/scripts/plugins/process-automation-health.ts b/lib/cli/scripts/plugins/process-automation-health.ts index 1de1268f14a..33a97566a94 100644 --- a/lib/cli/scripts/plugins/process-automation-health.ts +++ b/lib/cli/scripts/plugins/process-automation-health.ts @@ -18,31 +18,22 @@ import { PluginInterface } from './plugin-model'; import { logger } from '../logger'; import { PluginConfiguration } from './plugin-config'; +import { AlfrescoApi } from '@alfresco/js-api'; export class ProcessAutomationHealth { config: PluginConfiguration; - constructor( - private plugInInfo: PluginInterface, - private alfrescoJsApi: any - ) { - this.config = new PluginConfiguration( - this.plugInInfo, - this.alfrescoJsApi - ); + constructor(private plugInInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) { + this.config = new PluginConfiguration(this.plugInInfo, this.alfrescoJsApi); } - async isPluginEnabledFromAppConfiguration() { + async isPluginEnabledFromAppConfiguration(): Promise { try { const url = `${this.plugInInfo.host}/${this.plugInInfo.appName}/ui/${this.plugInInfo.uiName}/app.config.json`; const appConfig = await this.config.getAppConfig(url); let isEnabled = true; if (appConfig && appConfig.plugins && appConfig.plugins[this.plugInInfo.name]) { - logger.info( - `The plugin ${ - this.plugInInfo.name - } has been correctly configured in app.config.json` - ); + logger.info(`The plugin ${this.plugInInfo.name} has been correctly configured in app.config.json`); } else { this.logConfigurationError(); isEnabled = false; @@ -55,7 +46,7 @@ export class ProcessAutomationHealth { } } - async checkBackendHealth() { + async checkBackendHealth(): Promise { const url = `${this.plugInInfo.host}/${this.plugInInfo.appName}/rb/actuator/health`; let isBackendActive = true; try { @@ -68,20 +59,12 @@ export class ProcessAutomationHealth { } return isBackendActive; } catch (error) { - logger.error( - `${this.plugInInfo.host} is not reachable error: `, - error - ); + logger.error(`${this.plugInInfo.host} is not reachable error: `, error); return false; } } - private logConfigurationError(error?: any) { - logger.error( - `The plugin ${ - this.plugInInfo.name - } has not been correctly configured in app.config.json`, - error - ); + private logConfigurationError(error?: any): void { + logger.error(`The plugin ${this.plugInInfo.name} has not been correctly configured in app.config.json`, error); } } diff --git a/lib/cli/scripts/plugins/process-service-check-plugin.ts b/lib/cli/scripts/plugins/process-service-check-plugin.ts index 9e6fa4f6f7f..a076b5e2c1d 100644 --- a/lib/cli/scripts/plugins/process-service-check-plugin.ts +++ b/lib/cli/scripts/plugins/process-service-check-plugin.ts @@ -20,37 +20,35 @@ import { PluginInterface } from './plugin-model'; import { logger } from '../logger'; import { ProcessServiceHealth } from './process-services-health'; +import { AlfrescoApi } from '@alfresco/js-api'; export class ProcessServiceCheckPlugin { processServiceHealth: ProcessServiceHealth; - constructor( - private plugInInfo: PluginInterface, - private alfrescoJsApi: any - ) { - this.processServiceHealth = new ProcessServiceHealth( - this.plugInInfo, - this.alfrescoJsApi - ); + constructor(private plugInInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) { + this.processServiceHealth = new ProcessServiceHealth(this.plugInInfo, this.alfrescoJsApi); } - async checkProcessServicesPlugin() { + async checkProcessServicesPlugin(): Promise { let pluginStatus; try { const isPluginEnabled = await this.processServiceHealth.isPluginEnabledFromAppConfiguration(); const isBackendActive = await this.processServiceHealth.checkBackendHealth(); if (isPluginEnabled && isBackendActive) { - logger.info( - `The plugin ${ - this.plugInInfo.name - } has been correctly configured` - ); + logger.info(`The plugin ${this.plugInInfo.name} has been correctly configured`); pluginStatus = [{ PluginName: this.plugInInfo.name, Status: `${'Active'}`, BE: 'UP', FE: 'Enabled' }]; console.table(pluginStatus); } else { this.logConfigurationError(); - pluginStatus = [{ PluginName: this.plugInInfo.name, Status: 'Inactive', BE: isBackendActive ? 'UP' : 'DOWN', FE: isPluginEnabled ? 'Enabled' : 'Disabled' }]; + pluginStatus = [ + { + PluginName: this.plugInInfo.name, + Status: 'Inactive', + BE: isBackendActive ? 'UP' : 'DOWN', + FE: isPluginEnabled ? 'Enabled' : 'Disabled' + } + ]; console.table(pluginStatus); process.exit(1); } @@ -62,12 +60,7 @@ export class ProcessServiceCheckPlugin { } } - private logConfigurationError(error?: any) { - logger.error( - `The plugin ${ - this.plugInInfo.name - } has not been correctly configured`, - error - ); + private logConfigurationError(error?: any): void { + logger.error(`The plugin ${this.plugInInfo.name} has not been correctly configured`, error); } } diff --git a/lib/cli/scripts/plugins/process-services-health.ts b/lib/cli/scripts/plugins/process-services-health.ts index 015592c5779..5a992d376fe 100644 --- a/lib/cli/scripts/plugins/process-services-health.ts +++ b/lib/cli/scripts/plugins/process-services-health.ts @@ -18,26 +18,22 @@ import { PluginInterface } from './plugin-model'; import { logger } from '../logger'; import { PluginConfiguration } from './plugin-config'; +import { AlfrescoApi, SystemPropertiesApi } from '@alfresco/js-api'; export class ProcessServiceHealth { - config: PluginConfiguration; - constructor(private plugInInfo: PluginInterface, private alfrescoJsApi: any) { + constructor(private plugInInfo: PluginInterface, private alfrescoJsApi: AlfrescoApi) { this.config = new PluginConfiguration(this.plugInInfo, this.alfrescoJsApi); } - async isPluginEnabledFromAppConfiguration() { + async isPluginEnabledFromAppConfiguration(): Promise { try { const url = `${this.plugInInfo.host}/app.config.json`; const appConfig = await this.config.getAppConfig(url); let isEnabled = true; if (appConfig && appConfig.plugins && appConfig.plugins[this.plugInInfo.name]) { - logger.info( - `The plugin ${ - this.plugInInfo.name - } has been correctly configured in app.config.json` - ); + logger.info(`The plugin ${this.plugInInfo.name} has been correctly configured in app.config.json`); } else { this.logConfigurationError(); return (isEnabled = false); @@ -50,9 +46,10 @@ export class ProcessServiceHealth { } } - async checkBackendHealth() { + async checkBackendHealth(): Promise { try { - const systemProperties = await this.alfrescoJsApi.activiti.systemPropertiesApi.getProperties(); + const systemPropertiesApi = new SystemPropertiesApi(this.alfrescoJsApi); + const systemProperties = await systemPropertiesApi.getProperties(); let isBackendActive = true; if (systemProperties) { logger.info(`${this.plugInInfo.host} is UP!`); @@ -62,20 +59,12 @@ export class ProcessServiceHealth { } return isBackendActive; } catch (error) { - logger.error( - `${this.plugInInfo.host} is not reachable error: `, - error - ); + logger.error(`${this.plugInInfo.host} is not reachable error: `, error); return false; } } - private logConfigurationError(error?: any) { - logger.error( - `The plugin ${ - this.plugInInfo.name - } has not been correctly configured in app.config.json`, - error - ); + private logConfigurationError(error?: any): void { + logger.error(`The plugin ${this.plugInInfo.name} has not been correctly configured in app.config.json`, error); } } diff --git a/lib/cli/scripts/scan-env.ts b/lib/cli/scripts/scan-env.ts index 7c525b4f290..2a65095850e 100644 --- a/lib/cli/scripts/scan-env.ts +++ b/lib/cli/scripts/scan-env.ts @@ -15,12 +15,19 @@ * limitations under the License. */ -import { AlfrescoApi, PeopleApi, NodesApi, GroupsApi, SitesApi, SearchApi, AlfrescoApiConfig } from '@alfresco/js-api'; +import { AlfrescoApi, PeopleApi, NodesApi, GroupsApi, SitesApi, SearchApi } from '@alfresco/js-api'; +import { argv, exit } from 'node:process'; import program from 'commander'; import { logger } from './logger'; -interface PeopleTally { enabled: number; disabled: number } -interface RowToPrint { label: string; value: number } +interface PeopleTally { + enabled: number; + disabled: number; +} +interface RowToPrint { + label: string; + value: number; +} const MAX_ATTEMPTS = 1; const TIMEOUT = 180000; @@ -35,11 +42,10 @@ const bright = '\x1b[1m'; const red = '\x1b[31m'; const green = '\x1b[32m'; -let jsApiConnection: any; +let alfrescoApi: AlfrescoApi; let loginAttempts: number = 0; export default async function main(_args: string[]) { - // eslint-disable-next-line no-console console.log = () => {}; @@ -49,7 +55,7 @@ export default async function main(_args: string[]) { .option('--clientId [type]', 'sso client', 'alfresco') .option('-p, --password ', 'password ') .option('-u, --username ', 'username ') - .parse(process.argv); + .parse(argv); logger.info(`${cyan}${bright}Initiating environment scan...${reset}`); await attemptLogin(); @@ -67,20 +73,26 @@ export default async function main(_args: string[]) { } function generateTable(rowsToPrint: Array) { - const columnWidths = rowsToPrint.reduce((maxWidths, row: RowToPrint) => ({ + const columnWidths = rowsToPrint.reduce( + (maxWidths, row: RowToPrint) => ({ labelColumn: Math.max(maxWidths.labelColumn, row.label.length), valueColumn: Math.max(maxWidths.valueColumn, row.value.toString().length) - }), { labelColumn: 12, valueColumn: 1 }); + }), + { labelColumn: 12, valueColumn: 1 } + ); const horizontalLine = ''.padEnd(columnWidths.labelColumn + columnWidths.valueColumn + 5, '═'); - const headerText = 'ENVIRONM'.padStart(Math.floor((columnWidths.labelColumn + columnWidths.valueColumn + 3) / 2), ' ') - + 'ENT SCAN'.padEnd(Math.ceil((columnWidths.labelColumn + columnWidths.valueColumn + 3) / 2), ' '); + const headerText = + 'ENVIRONM'.padStart(Math.floor((columnWidths.labelColumn + columnWidths.valueColumn + 3) / 2), ' ') + + 'ENT SCAN'.padEnd(Math.ceil((columnWidths.labelColumn + columnWidths.valueColumn + 3) / 2), ' '); let tableString = `${grey}╒${horizontalLine}╕${reset} ${grey}│ ${bright}${cyan}${headerText} ${grey}│${reset} ${grey}╞${horizontalLine}╡${reset}`; - rowsToPrint.forEach(row => { - tableString += `\n${grey}│${reset} ${row.label.padEnd(columnWidths.labelColumn, ' ')} ${yellow}${row.value.toString().padEnd(columnWidths.valueColumn, ' ')} ${grey}│${reset}`; + rowsToPrint.forEach((row) => { + tableString += `\n${grey}│${reset} ${row.label.padEnd(columnWidths.labelColumn, ' ')} ${yellow}${row.value + .toString() + .padEnd(columnWidths.valueColumn, ' ')} ${grey}│${reset}`; }); tableString += `\n${grey}╘${horizontalLine}╛${reset}`; @@ -90,11 +102,12 @@ ${grey}╞${horizontalLine}╡${reset}`; async function attemptLogin() { logger.info(` Logging into ${yellow}${program.host}${reset} with user ${yellow}${program.username}${reset}`); try { - jsApiConnection = new AlfrescoApi({ + alfrescoApi = new AlfrescoApi({ provider: 'ALL', hostBpm: program.host, hostEcm: program.host, authType: 'OAUTH', + contextRoot: 'alfresco', oauth2: { host: `${program.host}/auth/realms/alfresco`, clientId: `${program.clientId}`, @@ -102,8 +115,8 @@ async function attemptLogin() { redirectUri: '/', implicitFlow: false } - } as unknown as AlfrescoApiConfig); - await jsApiConnection.login(program.username, program.password); + }); + await alfrescoApi.login(program.username, program.password); logger.info(` ${green}Login SSO successful${reset}`); } catch (err) { await handleLoginError(err); @@ -117,7 +130,7 @@ async function handleLoginError(loginError) { checkEnvReachable(loginError); loginAttempts++; if (MAX_ATTEMPTS === loginAttempts) { - if (loginError && loginError.response && loginError?.response?.text) { + if (loginError?.response?.text) { try { const parsedJson = JSON.parse(loginError?.response?.text); if (typeof parsedJson === 'object' && parsedJson.error) { @@ -150,20 +163,23 @@ async function getPeopleCount(skipCount: number = 0): Promise { logger.info(` Fetching number of users`); } try { - const peopleApi = new PeopleApi(jsApiConnection); + const peopleApi = new PeopleApi(alfrescoApi); const apiResult = await peopleApi.listPeople({ fields: ['enabled'], maxItems: MAX_PEOPLE_PER_PAGE, skipCount }); - const result: PeopleTally = apiResult.list.entries.reduce((peopleTally: PeopleTally, currentPerson) => { - if (currentPerson.entry.enabled) { - peopleTally.enabled++; - } else { - peopleTally.disabled++; - } - return peopleTally; - }, { enabled: 0, disabled: 0 }); + const result: PeopleTally = apiResult.list.entries.reduce( + (peopleTally: PeopleTally, currentPerson) => { + if (currentPerson.entry.enabled) { + peopleTally.enabled++; + } else { + peopleTally.disabled++; + } + return peopleTally; + }, + { enabled: 0, disabled: 0 } + ); if (apiResult.list.pagination.hasMoreItems) { const more = await getPeopleCount(apiResult.list.pagination.skipCount + MAX_PEOPLE_PER_PAGE); result.enabled += more.enabled; @@ -178,7 +194,7 @@ async function getPeopleCount(skipCount: number = 0): Promise { async function getHomeFoldersCount(): Promise { logger.info(` Fetching number of home folders`); try { - const nodesApi = new NodesApi(jsApiConnection); + const nodesApi = new NodesApi(alfrescoApi); const homesFolderApiResult = await nodesApi.listNodeChildren('-root-', { maxItems: 1, relativePath: USERS_HOME_RELATIVE_PATH @@ -192,7 +208,7 @@ async function getHomeFoldersCount(): Promise { async function getGroupsCount(): Promise { logger.info(` Fetching number of groups`); try { - const groupsApi = new GroupsApi(jsApiConnection); + const groupsApi = new GroupsApi(alfrescoApi); const groupsApiResult = await groupsApi.listGroups({ maxItems: 1 }); return groupsApiResult.list.pagination.totalItems; } catch (error) { @@ -203,7 +219,7 @@ async function getGroupsCount(): Promise { async function getSitesCount(): Promise { logger.info(` Fetching number of sites`); try { - const sitesApi = new SitesApi(jsApiConnection); + const sitesApi = new SitesApi(alfrescoApi); const sitesApiResult = await sitesApi.listSites({ maxItems: 1 }); return sitesApiResult.list.pagination.totalItems; } catch (error) { @@ -214,7 +230,7 @@ async function getSitesCount(): Promise { async function getFilesCount(): Promise { logger.info(` Fetching number of files`); try { - const searchApi = new SearchApi(jsApiConnection); + const searchApi = new SearchApi(alfrescoApi); const searchApiResult = await searchApi.search({ query: { query: 'select * from cmis:document', @@ -248,11 +264,11 @@ function handleError(error) { function failScript() { logger.error(`${red}${bright}Environment scan failed. Exiting${reset}`); - process.exit(0); + exit(0); } async function wait(ms: number) { - return new Promise(resolve => { + return new Promise((resolve) => { setTimeout(resolve, ms); }); } diff --git a/lib/content-services/src/lib/dialogs/download-zip/mock/download-zip-service.mock.ts b/lib/content-services/src/lib/dialogs/download-zip/mock/download-zip-service.mock.ts index ae8e1102886..b3a2476db1b 100644 --- a/lib/content-services/src/lib/dialogs/download-zip/mock/download-zip-service.mock.ts +++ b/lib/content-services/src/lib/dialogs/download-zip/mock/download-zip-service.mock.ts @@ -23,13 +23,13 @@ import { zipNode, downloadEntry } from './download-zip-data.mock'; export class AlfrescoApiServiceMock { nodeUpdated = new Subject(); alfrescoApiInitialized: ReplaySubject = new ReplaySubject(1); - alfrescoApi = new AlfrescoApiCompatibilityMock(); + alfrescoApi = new AlfrescoApiMock(); load() {} getInstance = () => this.alfrescoApi; } -class AlfrescoApiCompatibilityMock { +class AlfrescoApiMock { core = new CoreMock(); content = new ContentApiMock(); diff --git a/lib/core/src/lib/auth/oidc/view/authentication-confirmation/authentication-confirmation.component.spec.ts b/lib/core/src/lib/auth/oidc/view/authentication-confirmation/authentication-confirmation.component.spec.ts deleted file mode 100644 index 4a1f6c2d7d1..00000000000 --- a/lib/core/src/lib/auth/oidc/view/authentication-confirmation/authentication-confirmation.component.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * @license - * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { MockProvider } from 'ng-mocks'; -import { AuthService } from '../../auth.service'; -import { AuthenticationConfirmationComponent } from './authentication-confirmation.component'; - -describe('AuthenticationConfirmationComponent', () => { - let component: AuthenticationConfirmationComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [AuthenticationConfirmationComponent], - providers: [ - MockProvider(AuthService, { - loginCallback() { - return Promise.resolve(undefined); - } - }) - ], - imports: [RouterTestingModule] - }).compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(AuthenticationConfirmationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/lib/process-services/src/lib/form/services/external-alfresco-api.service.ts b/lib/process-services/src/lib/form/services/external-alfresco-api.service.ts index a4c3353bf4a..8fcd3656633 100644 --- a/lib/process-services/src/lib/form/services/external-alfresco-api.service.ts +++ b/lib/process-services/src/lib/form/services/external-alfresco-api.service.ts @@ -16,43 +16,12 @@ */ import { Injectable } from '@angular/core'; -import { - AlfrescoApiCompatibility, - ContentApi, - Node, NodesApi -} from '@alfresco/js-api'; -import { ReplaySubject, Subject } from 'rxjs'; - -@Injectable({ - providedIn: 'root' -}) -export class ExternalAlfrescoApiService { - - /** - * Publish/subscribe to events related to node updates. - */ - nodeUpdated = new Subject(); - - alfrescoApiInitialized: ReplaySubject = new ReplaySubject(1); - - protected alfrescoApi: AlfrescoApiCompatibility; - _nodesApi: NodesApi; - - getInstance(): AlfrescoApiCompatibility { - return this.alfrescoApi; - } - - get contentApi(): ContentApi { - return this.getInstance().content; - } - - get nodesApi(): NodesApi { - this._nodesApi = this._nodesApi ?? new NodesApi(this.getInstance()); - return this._nodesApi; - } +import { AlfrescoApi } from '@alfresco/js-api'; +import { AlfrescoApiService } from '@alfresco/adf-core'; +@Injectable({ providedIn: 'root' }) +export class ExternalAlfrescoApiService extends AlfrescoApiService { init(ecmHost: string, contextRoot: string) { - const domainPrefix = this.createPrefixFromHost(ecmHost); const config = { @@ -62,15 +31,15 @@ export class ExternalAlfrescoApiService { contextRoot, domainPrefix }; - this.initAlfrescoApi(config); + this.setup(config); this.alfrescoApiInitialized.next(true); } - protected initAlfrescoApi(config) { + private setup(config) { if (this.alfrescoApi) { - this.alfrescoApi.configureJsApi(config); + this.alfrescoApi.setConfig(config); } else { - this.alfrescoApi = new AlfrescoApiCompatibility(config); + this.alfrescoApi = new AlfrescoApi(config); } } diff --git a/lib/process-services/src/lib/form/widgets/content-widget/attach-file-widget-dialog.component.ts b/lib/process-services/src/lib/form/widgets/content-widget/attach-file-widget-dialog.component.ts index fe2eb65b699..57698741ced 100644 --- a/lib/process-services/src/lib/form/widgets/content-widget/attach-file-widget-dialog.component.ts +++ b/lib/process-services/src/lib/form/widgets/content-widget/attach-file-widget-dialog.component.ts @@ -17,12 +17,7 @@ import { Component, Inject, ViewEncapsulation, ViewChild } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { - AlfrescoApiService, - LoginDialogPanelComponent, - TranslationService, - AuthenticationService -} from '@alfresco/adf-core'; +import { AlfrescoApiService, LoginDialogPanelComponent, TranslationService, AuthenticationService } from '@alfresco/adf-core'; import { AttachFileWidgetDialogComponentData } from './attach-file-widget-dialog-component.interface'; import { DocumentListService, SitesService, SearchService } from '@alfresco/adf-content-services'; import { ExternalAlfrescoApiService } from '../../services/external-alfresco-api.service'; @@ -38,10 +33,10 @@ import { Node } from '@alfresco/js-api'; DocumentListService, SitesService, SearchService, - { provide: AlfrescoApiService, useClass: ExternalAlfrescoApiService } ] + { provide: AlfrescoApiService, useClass: ExternalAlfrescoApiService } + ] }) export class AttachFileWidgetDialogComponent { - @ViewChild('adfLoginPanel') loginPanel: LoginDialogPanelComponent; @@ -50,12 +45,14 @@ export class AttachFileWidgetDialogComponent { buttonActionName: string; chosenNode: Node[]; - constructor(private translation: TranslationService, - @Inject(MAT_DIALOG_DATA) public data: AttachFileWidgetDialogComponentData, - private externalApiService: AlfrescoApiService, - private authenticationService: AuthenticationService, - private matDialogRef: MatDialogRef) { - (externalApiService as any).init(data.ecmHost, data.context); + constructor( + private translation: TranslationService, + @Inject(MAT_DIALOG_DATA) public data: AttachFileWidgetDialogComponentData, + private externalApiService: AlfrescoApiService, + private authenticationService: AuthenticationService, + private matDialogRef: MatDialogRef + ) { + (externalApiService as ExternalAlfrescoApiService).init(data.ecmHost, data.context); this.action = data.actionName ? data.actionName.toUpperCase() : 'CHOOSE'; this.buttonActionName = `ATTACH-FILE.ACTIONS.${this.action}`; this.updateTitle('DROPDOWN.MY_FILES_OPTION'); @@ -64,13 +61,13 @@ export class AttachFileWidgetDialogComponent { updateExternalHost() { this.authenticationService.onLogin.subscribe(() => this.registerAndClose()); - if (this.externalApiService.getInstance().isLoggedIn()) { + if (this.isLoggedIn()) { this.registerAndClose(); } } - isLoggedIn() { - return this.externalApiService.getInstance().isLoggedIn(); + isLoggedIn(): boolean { + return !!this.externalApiService.getInstance()?.isLoggedIn(); } performLogin() { diff --git a/lib/process-services/src/lib/form/widgets/document/content.widget.ts b/lib/process-services/src/lib/form/widgets/document/content.widget.ts index 06971622dba..d49ee05b320 100644 --- a/lib/process-services/src/lib/form/widgets/document/content.widget.ts +++ b/lib/process-services/src/lib/form/widgets/document/content.widget.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { UrlService, LogService, ContentLinkModel, FormService, DownloadService } from '@alfresco/adf-core'; +import { UrlService, ContentLinkModel, FormService, DownloadService } from '@alfresco/adf-core'; import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewEncapsulation } from '@angular/core'; import { Observable } from 'rxjs'; import { ProcessContentService } from '../../services/process-content.service'; @@ -27,7 +27,6 @@ import { ProcessContentService } from '../../services/process-content.service'; encapsulation: ViewEncapsulation.None }) export class ContentWidgetComponent implements OnChanges { - /** The content id to show. */ @Input() id: string; @@ -54,12 +53,12 @@ export class ContentWidgetComponent implements OnChanges { content: ContentLinkModel; - constructor(protected formService: FormService, - private logService: LogService, - private downloadService: DownloadService, - private urlService: UrlService, - private processContentService: ProcessContentService) { - } + constructor( + protected formService: FormService, + private downloadService: DownloadService, + private urlService: UrlService, + private processContentService: ProcessContentService + ) {} ngOnChanges(changes: SimpleChanges) { const contentId = changes['id']; @@ -69,18 +68,16 @@ export class ContentWidgetComponent implements OnChanges { } loadContent(id: number) { - this.processContentService - .getFileContent(id) - .subscribe( - (response: ContentLinkModel) => { - this.content = new ContentLinkModel(response); - this.contentLoaded.emit(this.content); - this.loadThumbnailUrl(this.content); - }, - (error) => { - this.error.emit(error); - } - ); + this.processContentService.getFileContent(id).subscribe( + (response: ContentLinkModel) => { + this.content = new ContentLinkModel(response); + this.contentLoaded.emit(this.content); + this.loadThumbnailUrl(this.content); + }, + (error) => { + this.error.emit(error); + } + ); } loadThumbnailUrl(content: ContentLinkModel) { @@ -101,7 +98,6 @@ export class ContentWidgetComponent implements OnChanges { }, (error) => { this.error.emit(error); - } ); } @@ -117,7 +113,6 @@ export class ContentWidgetComponent implements OnChanges { (blob: Blob) => { content.contentBlob = blob; this.contentClick.emit(content); - this.logService.info('Content clicked' + content.id); this.formService.formContentClicked.next(content); }, (error) => { diff --git a/package-lock.json b/package-lock.json index 09b58c23fae..c219df37f15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -124,7 +124,6 @@ "lite-server": "^2.6.1", "mini-css-extract-plugin": "^1.6.0", "nconf": "^0.12.0", - "ng-mocks": "^14.8.0", "ng-packagr": "14.0.3", "nx": "14.4.2", "postcss": "^8.4.5", @@ -39760,20 +39759,6 @@ "version": "1.1.0", "license": "ISC" }, - "node_modules/ng-mocks": { - "version": "14.10.0", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/satanTime" - }, - "peerDependencies": { - "@angular/common": "5.0.0-alpha - 5 || 6.0.0-alpha - 6 || 7.0.0-alpha - 7 || 8.0.0-alpha - 8 || 9.0.0-alpha - 9 || 10.0.0-alpha - 10 || 11.0.0-alpha - 11 || 12.0.0-alpha - 12 || 13.0.0-alpha - 13 || 14.0.0-alpha - 14 || 15.0.0-alpha - 15 || 16.0.0-alpha - 16", - "@angular/core": "5.0.0-alpha - 5 || 6.0.0-alpha - 6 || 7.0.0-alpha - 7 || 8.0.0-alpha - 8 || 9.0.0-alpha - 9 || 10.0.0-alpha - 10 || 11.0.0-alpha - 11 || 12.0.0-alpha - 12 || 13.0.0-alpha - 13 || 14.0.0-alpha - 14 || 15.0.0-alpha - 15 || 16.0.0-alpha - 16", - "@angular/forms": "5.0.0-alpha - 5 || 6.0.0-alpha - 6 || 7.0.0-alpha - 7 || 8.0.0-alpha - 8 || 9.0.0-alpha - 9 || 10.0.0-alpha - 10 || 11.0.0-alpha - 11 || 12.0.0-alpha - 12 || 13.0.0-alpha - 13 || 14.0.0-alpha - 14 || 15.0.0-alpha - 15 || 16.0.0-alpha - 16", - "@angular/platform-browser": "5.0.0-alpha - 5 || 6.0.0-alpha - 6 || 7.0.0-alpha - 7 || 8.0.0-alpha - 8 || 9.0.0-alpha - 9 || 10.0.0-alpha - 10 || 11.0.0-alpha - 11 || 12.0.0-alpha - 12 || 13.0.0-alpha - 13 || 14.0.0-alpha - 14 || 15.0.0-alpha - 15 || 16.0.0-alpha - 16" - } - }, "node_modules/ng-packagr": { "version": "14.0.3", "dev": true, diff --git a/package.json b/package.json index 3e4a179d1e6..4b1aa31f2a8 100644 --- a/package.json +++ b/package.json @@ -168,7 +168,6 @@ "lite-server": "^2.6.1", "mini-css-extract-plugin": "^1.6.0", "nconf": "^0.12.0", - "ng-mocks": "^14.8.0", "ng-packagr": "14.0.3", "nx": "14.4.2", "postcss": "^8.4.5", @@ -226,4 +225,3 @@ "module": "./index.js", "typings": "./index.d.ts" } -