@digipolis/start-ui
Version:
242 lines (230 loc) • 7.38 kB
JavaScript
import path from 'path';
import chalk from 'chalk';
import replace from 'replace-in-file';
import { nodeConfig } from '../../config/back-end.config.js';
import { copyJob } from '../../utils/copy.js';
import debug from '../../utils/debug.js';
import { deleteFileSync, deleteFolderRecursive } from '../../utils/delete.js';
import { execPromise } from '../../utils/exec.js';
import { gitclone } from '../../utils/gitclone.js';
import { updateLog, errorLog } from '../../utils/log.js';
import { removeMatchedLines } from '../../utils/removeLine.js';
const { log } = console;
const generatorOptions = [
{
param: '-d, --database <database>',
description: 'Database (MongoDB, Postgres or none)',
fallback: 'mongodb',
},
{
param: '-A, --no-auth',
description: "Don't add basic authentication",
},
];
const questions = [
{
type: 'list',
name: 'database',
message: 'Which database would you like?',
choices: [{ value: 'postgres', name: 'Postgres' }, { value: 'mongodb', name: 'MongoDB' }, { value: undefined, name: "I don't need a database" }],
},
{
type: 'confirm',
name: 'auth',
message: 'Do you want your app to include Digipolis authentication?',
default: true,
},
];
function getQuestions() {
return questions;
}
function getOptions() {
return generatorOptions;
}
async function copyBaseProject(config) {
const { baseProject } = nodeConfig;
const { repository, tag, branch } = baseProject;
debug.logger(`Clone backend version: ${tag}`);
await gitclone(repository, tag, branch);
debug.logger('Copy files from repo');
if (config.frontend) {
debug.logger('Enable Frontend in Dockerfile.');
if (config.frontend === 'react') {
debug.logger('Enable React build');
await replace({
files: './tmp/Dockerfile',
from: ['COPY ./frontend /code/frontend'],
to: [`COPY ./frontend /code/frontend
RUN npm ci
RUN npm run build`],
});
} else if (config.frontend === 'angular') {
debug.logger('Enable angular build');
await replace({
files: './tmp/Dockerfile',
from: ['COPY ./frontend /code/frontend'],
to: [`COPY ./frontend /code/frontend
RUN npm ci
RUN npm run build:prod`],
});
}
} else {
debug.logger('No frontend');
await replace({
files: './tmp/Dockerfile',
from: [/COPY .\/frontend \/code\/frontend/g, /WORKDIR \/code\/frontend/g],
to: ['# COPY ./frontend /code/frontend', '# WORKDIR /code/frontend'],
});
deleteFileSync('./tmp/backend/test/routes/frontend.test.js');
}
const copyJobs = [
{ source: './tmp/.digipolis.json', destination: './', type: 'file' },
{ source: './tmp/CHANGELOG.md', destination: './', type: 'file' },
{ source: './tmp/Dockerfile', destination: './', type: 'file' },
{ source: './tmp/README.md', destination: './', type: 'file' },
{ source: './tmp/backend', destination: './', type: 'folder' },
{ source: './tmp/.editorconfig', destination: './', type: 'file' },
{ source: './tmp/docker-compose.ci.yml', destination: './', type: 'file' },
{ source: './tmp/docker-compose.yml', destination: './', type: 'file' },
];
await copyJob(copyJobs);
debug.logger('Cleanup tmp folder');
deleteFolderRecursive('./tmp');
}
async function setDB(db) {
if (db === 'mongodb') {
updateLog('Installing MongoDB...');
debug.logger('MongoDB is the default. Removing Postgres comments');
await replace({
files: `${__backenddir}/src/controllers/examples.js`,
from: [
"// import { getExampleById, getAllExamples } from '../services/pgexample.js';",
],
to: [
'',
],
});
await replace({
files: `${__backenddir}/src/app.js`,
from: [
"// import db from './helpers/postgres.helper.js'",
],
to: [
'',
],
});
} else if (db === 'postgres') {
debug.logger('Enable postgres');
await replace({
files: `${__backenddir}/src/controllers/examples.js`,
from: [
"import { getExampleById, getAllExamples } from '../services/example.js';",
"// import { getExampleById, getAllExamples } from '../services/pgexample.js';",
],
to: [
"import { getExampleById, getAllExamples } from '../services/pgexample.js';",
],
});
await replace({
files: `${__backenddir}/src/app.js`,
from: [
"import db from './helpers/mongoose.helper.js';",
"// import db from './helpers/postgres.helper.js';",
],
to: [
'',
"import db from './helpers/postgres.helper.js';",
],
});
deleteFileSync(`${__backenddir}/src/models/example.js`);
deleteFileSync(`${__backenddir}/test/unit/mongoose.test.js`);
deleteFileSync(`${__backenddir}/test/routes/example.test.js`);
await removeMatchedLines(`${__backenddir}/package.json`, 'mongoose');
} else {
debug.logger('Remove DB files');
deleteFileSync(`${__backenddir}/src/helpers/mongoose.helper.js`);
deleteFileSync(`${__backenddir}/src/routes/example.router.js`);
deleteFileSync(`${__backenddir}/test/routes/example.test.js`);
debug.logger('remove db references');
deleteFolderRecursive(`${__backenddir}/src/models`);
await replace({
files: `${__backenddir}/src/app.js`,
from: [
"import db from './helpers/mongoose.helper.js';",
"// import db from './helpers/postgres.helper.js';",
],
to: [
'',
'',
],
});
await replace({
files: `${__backenddir}/src/app.js`,
from: [
'await db.initializeDatabase();',
],
to: [
'',
],
});
await replace({
files: `${__backenddir}/src/app.js`,
from: [
'db.closeDatabaseConnection()',
],
to: [
'',
],
});
await replace({
files: `${__backenddir}/src/services/example.js`,
from: [
"import Example from '../models/example.js';",
'return Example.findById(exampleId);',
'return Example.find();',
],
to: [
'',
'return true',
'return true',
],
});
await removeMatchedLines(`${__backenddir}/src/routes/api.router.js`, 'example');
await removeMatchedLines(`${__backenddir}/package.json`, 'mongoose');
}
}
async function setAuth(auth) {
if (auth) {
updateLog('Adding M-profile authentication...');
debug.logger('Auth is included. Nothing to replace');
} else {
debug.logger('Remove Auth files');
deleteFileSync(`${__backenddir}/src/routes/auth.router.js`);
debug.logger('remove auth references');
deleteFolderRecursive(`${__backenddir}/src/models`);
await removeMatchedLines(`${__backenddir}/src/routes/index.js`, 'setupAuthRoutes');
await removeMatchedLines(`${__backenddir}/package.json`, '@digipolis/auth');
}
}
async function installPackages() {
await execPromise('npm', ['install'], { cwd: path.resolve(__backenddir) });
}
async function start(options) {
updateLog('Setting up Node.js...');
try {
await copyBaseProject(options);
await setDB(options.database);
await setAuth(options.auth);
await installPackages();
log(
chalk.cyan.bold('Done with BFF setup'),
);
} catch (e) {
errorLog(e);
}
}
export default {
getOptions,
getQuestions,
start,
};