strapi/packages/strapi-generate-new/lib/create-customized-project.js

170 lines
4.1 KiB
JavaScript
Raw Normal View History

2019-06-20 16:38:15 +02:00
'use strict';
const { join } = require('path');
const fse = require('fs-extra');
const inquirer = require('inquirer');
const execa = require('execa');
const { merge, pick } = require('lodash');
const stopProcess = require('./utils/stop-process');
const { trackUsage } = require('./utils/usage');
const defaultConfigs = require('./utils/db-configs');
const clientDependencies = require('./utils/db-client-dependencies');
const dbQuestions = require('./utils/db-questions');
const createProject = require('./create-project');
module.exports = async scope => {
await trackUsage({ event: 'didChooseCustomDatabase', scope });
const configuration = await askDbInfosAndTest(scope).catch(error => {
return trackUsage({ event: 'didNotConnectDatabase', scope, error }).then(
() => {
throw error;
}
);
});
console.log('Creating a project with custom database options');
await trackUsage({ event: 'didConnectDatabase', scope });
return createProject(scope, configuration);
};
const MAX_RETRIES = 5;
async function askDbInfosAndTest(scope) {
let retries = 0;
async function loop() {
// else ask for the client name
const { client, connection } = await askDatabaseInfos(scope);
const configuration = {
client,
connection,
2019-07-03 11:20:14 +02:00
dependencies: clientDependencies({ scope, client }),
2019-06-20 16:38:15 +02:00
};
await testDatabaseConnection({
scope,
configuration,
})
.then(
() => fse.remove(scope.tmpPath),
err => {
return fse.remove(scope.tmpPath).then(() => {
throw err;
});
}
)
.catch(err => {
if (retries < MAX_RETRIES - 1) {
console.log(`⛔️ Connection test failed: ${err.message}`);
if (scope.debug) {
console.log('Full error log:');
console.log(err);
}
console.log('Retrying...');
retries++;
return loop();
}
console.log(err);
stopProcess(
`️⛔️ Could not connect to your database after ${MAX_RETRIES} tries. Try to check your database configuration an retry.`
);
});
return configuration;
}
return loop();
}
async function testDatabaseConnection({ scope, configuration }) {
const { client } = configuration;
if (client === 'sqlite') return;
await installDatabaseTestingDep({
scope,
configuration,
});
const connectivityFile = join(
scope.tmpPath,
'node_modules',
configuration.connection.connector,
'lib',
'utils',
'connectivity.js'
);
const tester = require(connectivityFile);
return tester({ scope, connection: configuration.connection });
}
const SETTINGS_FIELDS = [
'database',
'host',
'srv',
'port',
'username',
'password',
'filename',
];
const OPTIONS_FIELDS = ['authenticationDatabase'];
async function askDatabaseInfos(scope) {
const { client } = await inquirer.prompt([
{
type: 'list',
name: 'client',
message: 'Choose your default database client',
choices: ['sqlite', 'postgres', 'mysql', 'mongo'],
default: 'sqlite',
},
]);
const responses = await inquirer.prompt(
dbQuestions[client].map(q => q({ scope, client }))
);
const connection = merge({}, defaultConfigs[client] || {}, {
settings: pick(responses, SETTINGS_FIELDS),
options: pick(responses, OPTIONS_FIELDS),
});
if (responses.ssl === true) {
if (client === 'mongo') {
connection.options.ssl = true;
} else {
connection.settings.ssl = true;
}
}
return {
client,
connection,
};
}
async function installDatabaseTestingDep({ scope, configuration }) {
2019-07-02 17:38:06 +02:00
let packageCmd = scope.useYarn
2019-06-20 16:38:15 +02:00
? `yarnpkg --cwd ${scope.tmpPath} add`
: `npm install --prefix ${scope.tmpPath}`;
// Manually create the temp directory for yarn
2019-07-02 17:38:06 +02:00
if (scope.useYarn) {
2019-06-20 16:38:15 +02:00
await fse.ensureDir(scope.tmpPath);
}
const depArgs = Object.keys(configuration.dependencies).map(dep => {
return `${dep}@${configuration.dependencies[dep]}`;
});
const cmd = `${packageCmd} ${depArgs.join(' ')}`;
await execa.shell(cmd);
}