Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jest.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const config = {
bail: true,
modulePathIgnorePatterns: ['tmp'],
// coverage
collectCoverage: true, // TODO: enable
collectCoverage: true,
coverageDirectory: '<rootDir>/__testing__/coverage',
coveragePathIgnorePatterns: [
'/node_modules/',
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "monux-cli",
"version": "2.0.9",
"version": "2.1.0",
"license": "MIT",
"main": "index.js",
"engines": {
Expand Down
2 changes: 1 addition & 1 deletion src/angular/angular.utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ export abstract class AngularUtilities {
{ defaultImport: false, element: 'OfflineService', path: './services/offline.service' }
]
);
// TODO: enable OfflineRequestInterceptor
// TODO: enable OfflineRequestInterceptor. Need to fix parsing of provideServiceWorker first.
// await this.addProvider(
// root,
// { provide: 'HTTP_INTERCEPTORS', useClass: 'OfflineRequestInterceptor' as any, multi: true },
Expand Down
4 changes: 3 additions & 1 deletion src/commands/add/add-angular/add-angular.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,10 @@ export class AddAngularCommand extends AddCommand<AddAngularConfiguration> {
const newProject: WorkspaceProject = await WorkspaceUtilities.findProjectOrFail(config.name);
await FsUtilities.updateFile(getPath(newProject.path, 'src', 'app', 'app.component.html'), '', 'replace');
await AngularUtilities.addProvider(newProject.path, 'provideHttpClient(withInterceptorsFromDi(), withFetch())', [
// eslint-disable-next-line sonar/no-duplicate-string
{ defaultImport: false, element: 'provideHttpClient', path: '@angular/common/http' },
{ defaultImport: false, element: 'withInterceptorsFromDi', path: '@angular/common/http' }
{ defaultImport: false, element: 'withInterceptorsFromDi', path: '@angular/common/http' },
{ defaultImport: false, element: 'withFetch', path: '@angular/common/http' }
]);
return newProject.path;
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/add/add-loopback/add-loopback-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('AddLoopbackCommand', () => {
'Email of the default user': 'test@test.com',
'Password of the default user': 'stringstring',
'Name of the frontend where the reset password ui is implemented': 'admin',
'Compose service': 'NEW',
'Database compose service': 'NEW',
'Compose service name': 'db',
'Database name': 'sandbox',
'database type': DbType.POSTGRES
Expand Down
28 changes: 14 additions & 14 deletions src/commands/add/add-loopback/add-loopback.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { APPS_DIRECTORY_NAME, PROD_DOCKER_COMPOSE_FILE_NAME, DOCKER_FILE_NAME, E
import { DbUtilities } from '../../../db';
import { DockerUtilities } from '../../../docker';
import { FsUtilities, QuestionsFor } from '../../../encapsulation';
import { DefaultEnvKeys, EnvironmentVariableKey, EnvUtilities } from '../../../env';
import { DefaultEnvKeys, EnvUtilities } from '../../../env';
import { EslintUtilities } from '../../../eslint';
import { LbDatabaseConfig, LoopbackUtilities } from '../../../loopback';
import { NpmPackage, NpmUtilities } from '../../../npm';
Expand Down Expand Up @@ -179,11 +179,6 @@ export class AddLoopbackCommand extends AddCommand<AddLoopbackConfiguration> {
await NpmUtilities.install(projectName, [NpmPackage.LOOPBACK_CONNECTOR_POSTGRES]);
await LoopbackUtilities.runCommand(root, `datasource ${databaseName}`, { '--config': lbDatabaseConfig, '--yes': true });

const PASSWORD_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbPassword(dbServiceName, databaseName);
const USER_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbUser(dbServiceName, databaseName);
const DATABASE_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbName(dbServiceName, databaseName);
const HOST_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbHost(dbServiceName);

const dataSourcePath: string = getPath(root, 'src', 'datasources', `${toKebabCase(databaseName)}.datasource.ts`);
await TsUtilities.addImportStatements(
dataSourcePath,
Expand All @@ -197,11 +192,11 @@ export class AddLoopbackCommand extends AddCommand<AddLoopbackConfiguration> {
[
'const config = {',
' url: \'\',',
` host: environment.${HOST_ENV_VARIABLE},`,
` host: environment.${DefaultEnvKeys.dbHost(dbServiceName)},`,
' port: 5432,',
` user: environment.${USER_ENV_VARIABLE},`,
` password: environment.${PASSWORD_ENV_VARIABLE},`,
` database: environment.${DATABASE_ENV_VARIABLE},`
` user: environment.${DefaultEnvKeys.dbUser(dbServiceName, databaseName)},`,
` password: environment.${DefaultEnvKeys.dbPassword(dbServiceName, databaseName)},`,
` database: environment.${DefaultEnvKeys.dbName(dbServiceName, databaseName)},`
].join('\n')
);
await FsUtilities.replaceInFile(
Expand All @@ -222,10 +217,15 @@ export class AddLoopbackCommand extends AddCommand<AddLoopbackConfiguration> {
);
const environmentModel: string = getPath(root, 'src', 'environment', ENVIRONMENT_MODEL_TS_FILE_NAME);

await EnvUtilities.addProjectVariableKey(projectName, environmentModel, PASSWORD_ENV_VARIABLE, true);
await EnvUtilities.addProjectVariableKey(projectName, environmentModel, USER_ENV_VARIABLE, true);
await EnvUtilities.addProjectVariableKey(projectName, environmentModel, DATABASE_ENV_VARIABLE, true);
await EnvUtilities.addProjectVariableKey(projectName, environmentModel, HOST_ENV_VARIABLE, true);
await EnvUtilities.addProjectVariableKey(
projectName,
environmentModel,
DefaultEnvKeys.dbPassword(dbServiceName, databaseName),
true
);
await EnvUtilities.addProjectVariableKey(projectName, environmentModel, DefaultEnvKeys.dbUser(dbServiceName, databaseName), true);
await EnvUtilities.addProjectVariableKey(projectName, environmentModel, DefaultEnvKeys.dbName(dbServiceName, databaseName), true);
await EnvUtilities.addProjectVariableKey(projectName, environmentModel, DefaultEnvKeys.dbHost(dbServiceName), true);
}

private async createProject(config: AddLoopbackConfiguration): Promise<string> {
Expand Down
32 changes: 13 additions & 19 deletions src/commands/add/add-wordpress/add-wordpress.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { DEV_DOCKER_COMPOSE_FILE_NAME } from '../../../constants';
import { DbType, DbUtilities } from '../../../db';
import { ComposeService, DockerUtilities } from '../../../docker';
import { QuestionsFor } from '../../../encapsulation';
import { DefaultEnvKeys, EnvUtilities } from '../../../env';
import { DefaultEnvKeys } from '../../../env';
import { OmitStrict } from '../../../types';
import { toKebabCase, toSnakeCase } from '../../../utilities';
import { toKebabCase } from '../../../utilities';
import { AddCommand, AddConfiguration } from '../models';

/**
Expand All @@ -31,22 +31,16 @@ export class AddWordpressCommand extends AddCommand<AddWordpressConfiguration> {

override async run(): Promise<void> {
const config: AddWordpressConfiguration = await this.getConfig();
// TODO: make calculated variables based on subDomain and port.
await EnvUtilities.addStaticVariable({
key: DefaultEnvKeys.domain(config.name),
required: true,
type: 'string',
value: 'localhost'
});
await EnvUtilities.addStaticVariable({ key: DefaultEnvKeys.baseUrl(config.name), required: true, type: 'string', value: 'http://localhost' });
const { dbServiceName } = await DbUtilities.configureDb(config.name, DbType.MARIADB);
await this.createProject(config, dbServiceName);
const { dbServiceName, databaseName } = await DbUtilities.configureDb(config.name, DbType.MARIADB);
await this.createProject(config, dbServiceName, databaseName);
}

private async createProject(config: AddWordpressConfiguration, dbServiceName: string, version: string = '6.1'): Promise<void> {
const DB_PASSWORD_ENV_VARIABLE: string = `${toSnakeCase(config.name)}_db_password`;
const DB_USER_ENV_VARIABLE: string = `${toSnakeCase(config.name)}_db_user`;
const DB_NAME_ENV_VARIABLE: string = `${toSnakeCase(config.name)}_database`;
private async createProject(
config: AddWordpressConfiguration,
dbServiceName: string,
databaseName: string,
version: string = '6.1'
): Promise<void> {
const serviceDefinition: ComposeService = {
name: config.name,
image: `wordpress:${version}`,
Expand All @@ -63,15 +57,15 @@ export class AddWordpressCommand extends AddCommand<AddWordpressConfiguration> {
},
{
key: 'WORDPRESS_DB_USER',
value: `\${${DB_USER_ENV_VARIABLE}}`
value: `\${${DefaultEnvKeys.dbUser(dbServiceName, databaseName)}}`
},
{
key: 'WORDPRESS_DB_PASSWORD',
value: `\${${DB_PASSWORD_ENV_VARIABLE}}`
value: `\${${DefaultEnvKeys.dbPassword(dbServiceName, databaseName)}}`
},
{
key: 'WORDPRESS_DB_NAME',
value: `\${${DB_NAME_ENV_VARIABLE}}`
value: `\${${DefaultEnvKeys.dbName(dbServiceName, databaseName)}}`
}
]
};
Expand Down
95 changes: 59 additions & 36 deletions src/db/db.utilities.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dirent } from 'fs';

import { DATABASES_DIRECTORY_NAME, DEV_DOCKER_COMPOSE_FILE_NAME, DockerComposeFileName } from '../constants';
import { DATABASES_DIRECTORY_NAME, DEV_DOCKER_COMPOSE_FILE_NAME, DockerComposeFileName, GLOBAL_ENVIRONMENT_MODEL_FILE_NAME } from '../constants';
import { ComposeService, DockerUtilities } from '../docker';
import { FsUtilities, InquirerUtilities, JsonUtilities, QuestionsFor } from '../encapsulation';
import { DefaultEnvKeys, EnvironmentVariableKey, EnvUtilities } from '../env';
Expand Down Expand Up @@ -132,7 +132,7 @@ export abstract class DbUtilities {
const baseDbQuestions: QuestionsFor<DbConfig> = {
dbServiceName: {
type: 'select',
message: 'Compose service',
message: 'Database compose service',
choices: ['NEW', ...(await this.getAvailableDatabases()).map(db => db.name)],
default: 'NEW'
},
Expand Down Expand Up @@ -230,12 +230,6 @@ export abstract class DbUtilities {
}

private static async createMariaDbDatabase(dbServiceName: string, databaseName: string): Promise<void> {
const PASSWORD_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbPassword(dbServiceName, databaseName);
const USER_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbUser(dbServiceName, databaseName);
const DATABASE_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbName(dbServiceName, databaseName);
const HOST_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbHost(dbServiceName);
const ROOT_PASSWORD_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbRootPassword(dbServiceName);

const user: string = `${toSnakeCase(databaseName)}_user`;
const password: string = generatePlaceholderPassword();
const rootPassword: string = generatePlaceholderPassword();
Expand All @@ -256,7 +250,7 @@ export abstract class DbUtilities {
environment: [
{
key: 'MARIADB_ROOT_PASSWORD',
value: `\${${ROOT_PASSWORD_ENV_VARIABLE}}`
value: `\${${DefaultEnvKeys.dbRootPassword(dbServiceName)}}`
}
]
};
Expand All @@ -274,45 +268,57 @@ export abstract class DbUtilities {
);
await DockerUtilities.addVolumeToCompose(`${toKebabCase(dbServiceName)}-data`, DEV_DOCKER_COMPOSE_FILE_NAME);
await EnvUtilities.addStaticVariable({
key: PASSWORD_ENV_VARIABLE,
key: DefaultEnvKeys.dbPassword(dbServiceName, databaseName),
value: password,
required: true,
type: 'string'
});
await EnvUtilities.addStaticVariable({
key: USER_ENV_VARIABLE,
key: DefaultEnvKeys.dbUser(dbServiceName, databaseName),
value: user,
required: true,
type: 'string'
});
await EnvUtilities.addStaticVariable({
key: DATABASE_ENV_VARIABLE,
key: DefaultEnvKeys.dbName(dbServiceName, databaseName),
value: databaseName,
required: true,
type: 'string'
});
// TODO: make calculated variable either "localhost" for dev or "serviceName" for local/prod.
await EnvUtilities.addStaticVariable({
key: HOST_ENV_VARIABLE,
value: 'localhost',
key: DefaultEnvKeys.dbRootPassword(dbServiceName),
value: rootPassword,
required: true,
type: 'string'
});
await EnvUtilities.addStaticVariable({
key: ROOT_PASSWORD_ENV_VARIABLE,
value: rootPassword,

await EnvUtilities.addCalculatedVariable({
key: DefaultEnvKeys.dbHost(dbServiceName),
required: true,
type: 'string'
type: 'string',
value: (env, fileName) => {
switch (fileName) {
case 'dev.docker-compose.yaml': {
return 'localhost';
}
case 'docker-compose.yaml':
case 'local.docker-compose.yaml': {
return 'DB_SERVICE_NAME_PLACEHOLDER';
}
}

}
});

const environmentModelFilePath: string = getPath(GLOBAL_ENVIRONMENT_MODEL_FILE_NAME);
await FsUtilities.replaceInFile(
environmentModelFilePath,
'DB_SERVICE_NAME_PLACEHOLDER',
dbServiceName
);
}

private static async createPostgresDatabase(dbServiceName: string, databaseName: string): Promise<void> {
const PASSWORD_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbPassword(dbServiceName, databaseName);
const USER_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbUser(dbServiceName, databaseName);
const DATABASE_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbName(dbServiceName, databaseName);
const HOST_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbHost(dbServiceName);
const ROOT_PASSWORD_ENV_VARIABLE: EnvironmentVariableKey = DefaultEnvKeys.dbRootPassword(dbServiceName);

const user: string = `${toSnakeCase(databaseName)}_user`;
const password: string = generatePlaceholderPassword();
const rootPassword: string = generatePlaceholderPassword();
Expand All @@ -333,7 +339,7 @@ export abstract class DbUtilities {
environment: [
{
key: 'POSTGRES_PASSWORD',
value: `\${${ROOT_PASSWORD_ENV_VARIABLE}}`
value: `\${${DefaultEnvKeys.dbRootPassword(dbServiceName)}}`
}
]
};
Expand All @@ -351,36 +357,53 @@ export abstract class DbUtilities {
);
await DockerUtilities.addVolumeToCompose(`${toKebabCase(dbServiceName)}-data`, DEV_DOCKER_COMPOSE_FILE_NAME);
await EnvUtilities.addStaticVariable({
key: PASSWORD_ENV_VARIABLE,
key: DefaultEnvKeys.dbPassword(dbServiceName, databaseName),
value: password,
required: true,
type: 'string'
});
await EnvUtilities.addStaticVariable({
key: USER_ENV_VARIABLE,
key: DefaultEnvKeys.dbUser(dbServiceName, databaseName),
value: user,
required: true,
type: 'string'
});
await EnvUtilities.addStaticVariable({
key: DATABASE_ENV_VARIABLE,
key: DefaultEnvKeys.dbName(dbServiceName, databaseName),
value: databaseName,
required: true,
type: 'string'
});
// TODO: make calculated variable either "localhost" for dev or "serviceName" for local/prod.
await EnvUtilities.addStaticVariable({
key: HOST_ENV_VARIABLE,
value: 'localhost',
key: DefaultEnvKeys.dbRootPassword(dbServiceName),
value: rootPassword,
required: true,
type: 'string'
});
await EnvUtilities.addStaticVariable({
key: ROOT_PASSWORD_ENV_VARIABLE,
value: rootPassword,

await EnvUtilities.addCalculatedVariable({
key: DefaultEnvKeys.dbHost(dbServiceName),
required: true,
type: 'string'
type: 'string',
value: (env, fileName) => {
switch (fileName) {
case 'dev.docker-compose.yaml': {
return 'localhost';
}
case 'docker-compose.yaml':
case 'local.docker-compose.yaml': {
return 'DB_SERVICE_NAME_PLACEHOLDER';
}
}

}
});
const environmentModelFilePath: string = getPath(GLOBAL_ENVIRONMENT_MODEL_FILE_NAME);
await FsUtilities.replaceInFile(
environmentModelFilePath,
'DB_SERVICE_NAME_PLACEHOLDER',
dbServiceName
);
}

private static isDatabaseService(service: ComposeService): boolean {
Expand Down
Loading
Loading