271 lines
8.9 KiB
JavaScript
Raw Normal View History

2016-03-18 11:12:50 +01:00
'use strict';
/**
* Module dependencies
*/
// Node.js core.
const path = require('path');
const os = require('os');
const crypto = require('crypto');
const exec = require('child_process').exec;
2018-05-04 17:50:39 +02:00
2016-03-18 11:12:50 +01:00
// Public node modules.
const _ = require('lodash');
2018-06-22 15:25:15 +02:00
const {cyan} = require('chalk');
2016-03-18 11:12:50 +01:00
const fs = require('fs-extra');
2018-01-05 15:17:59 +01:00
const inquirer = require('inquirer');
2018-01-19 15:41:01 +01:00
const shell = require('shelljs');
2016-03-18 11:12:50 +01:00
2016-03-25 22:22:34 +01:00
// Logger.
const { packageManager } = require('strapi-utils');
2016-03-25 22:22:34 +01:00
2016-03-18 11:12:50 +01:00
/**
* This `before` function is run before generating targets.
* Validate, configure defaults, get extra dependencies, etc.
*
* @param {Object} scope
* @param {Function} cb
*/
2018-05-04 17:50:39 +02:00
/* eslint-disable no-useless-escape */
module.exports = (scope, cb) => {
2016-03-18 11:12:50 +01:00
// App info.
const hasDatabaseConfig = !!scope.database;
2016-03-18 11:12:50 +01:00
_.defaults(scope, {
2017-06-08 17:16:20 +01:00
name: scope.name === '.' || !scope.name ? scope.name : path.basename(process.cwd()),
2016-03-18 11:12:50 +01:00
author: process.env.USER || 'A Strapi developer',
email: process.env.EMAIL || '',
year: (new Date()).getFullYear(),
license: 'MIT',
database: {}
2016-03-18 11:12:50 +01:00
});
// Make changes to the rootPath where the Strapi project will be created.
scope.rootPath = path.resolve(process.cwd(), scope.name || '');
2018-06-25 16:05:14 -05:00
scope.tmpPath = path.resolve(os.tmpdir(), `strapi${ crypto.randomBytes(6).toString('hex') }`);
2016-03-18 11:12:50 +01:00
// Ensure we aren't going to inadvertently delete any files.
try {
const files = fs.readdirSync(scope.rootPath);
2018-02-12 19:08:37 +01:00
if (files.length > 1) {
2018-06-22 15:25:15 +02:00
return console.log(`⛔️ ${cyan('strapi new')} can only be called in an empty directory.`);
2016-03-18 11:12:50 +01:00
}
2016-03-25 22:22:34 +01:00
} catch (err) {
2016-03-18 11:12:50 +01:00
// ...
}
2018-06-22 15:25:15 +02:00
console.log('Let\s configurate the connection to your database:');
2018-01-08 12:00:56 +01:00
if (hasDatabaseConfig) {
2018-06-22 15:25:15 +02:00
console.log(`Database determined by CLI args: ${scope.database.settings.client}`);
}
2018-01-08 12:00:56 +01:00
const connectionValidation = () => {
2018-01-10 18:08:43 +01:00
const databaseChoices = [
2018-01-10 14:45:32 +01:00
{
2018-10-09 14:41:56 +02:00
name: 'MongoDB',
2018-01-10 14:45:32 +01:00
value: {
database: 'mongo',
2018-07-11 16:23:14 +02:00
connector: 'strapi-hook-mongoose'
}
2018-01-10 14:45:32 +01:00
},
{
name: 'Postgres',
value: {
database: 'postgres',
2018-07-11 16:23:14 +02:00
connector: 'strapi-hook-bookshelf',
2018-01-10 14:45:32 +01:00
module: 'pg'
}
},
{
name: 'MySQL',
value: {
database: 'mysql',
2018-07-11 16:23:14 +02:00
connector: 'strapi-hook-bookshelf',
2018-01-10 14:45:32 +01:00
module: 'mysql'
}
}
];
inquirer
2018-05-04 17:50:39 +02:00
.prompt([
{
when: !hasDatabaseConfig,
type: 'list',
name: 'client',
message: 'Choose your main database:',
choices: databaseChoices,
default: () => {
if (scope.client) {
return _.findIndex(databaseChoices, { value: _.omit(scope.client, ['version'])});
}
}
2018-01-08 12:00:56 +01:00
}
2018-05-04 17:50:39 +02:00
])
.then(answers => {
if (hasDatabaseConfig) {
const databaseChoice = _.find(databaseChoices, ['value.database', scope.database.settings.client]);
scope.database.connector = databaseChoice.value.connector;
answers.client = {
...databaseChoice.value
};
} else {
_.assign(scope.database, {
connector: answers.client.connector,
settings: {
client: answers.client.database
2018-01-08 12:00:56 +01:00
},
2018-05-04 17:50:39 +02:00
options: {}
});
}
scope.client = answers.client;
2018-05-04 17:50:39 +02:00
const asyncFn = [
new Promise(resolve => {
inquirer
.prompt([
{
when: !hasDatabaseConfig,
type: 'input',
name: 'database',
message: 'Database name:',
2018-08-08 11:50:31 +02:00
default: _.get(scope.database, 'database', scope.name)
2018-05-04 17:50:39 +02:00
},
{
when: !hasDatabaseConfig,
type: 'input',
name: 'host',
message: 'Host:',
default: _.get(scope.database, 'host', '127.0.0.1')
},
{
when: !hasDatabaseConfig && scope.client.database === 'mongo',
type: 'boolean',
name: 'srv',
2018-08-27 14:01:56 +02:00
message: '+srv connection:',
default: _.get(scope.database, 'srv', false)
},
2018-05-04 17:50:39 +02:00
{
when: !hasDatabaseConfig,
type: 'input',
name: 'port',
message: `Port${scope.client.database === 'mongo' ? ' (It will be ignored if you enable +srv)' : ''}:`,
2018-05-04 17:50:39 +02:00
default: (answers) => { // eslint-disable-line no-unused-vars
if (_.get(scope.database, 'port')) {
return scope.database.port;
}
2018-01-08 12:00:56 +01:00
2018-05-04 17:50:39 +02:00
const ports = {
mongo: 27017,
postgres: 5432,
2018-05-07 16:03:35 +02:00
mysql: 3306
2018-05-04 17:50:39 +02:00
};
2018-05-04 17:50:39 +02:00
return ports[scope.client.database];
}
},
{
when: !hasDatabaseConfig,
type: 'input',
name: 'username',
message: 'Username:',
default: _.get(scope.database, 'username', undefined)
},
{
when: !hasDatabaseConfig,
type: 'password',
name: 'password',
message: 'Password:',
mask: '*',
default: _.get(scope.database, 'password', undefined)
},
{
when: !hasDatabaseConfig && scope.client.database === 'mongo',
type: 'input',
name: 'authenticationDatabase',
2018-09-02 03:28:22 +09:00
message: 'Authentication database (Maybe "admin" or blank):',
default: _.get(scope.database, 'authenticationDatabase', undefined)
2018-05-04 17:50:39 +02:00
},
{
when: !hasDatabaseConfig && scope.client.database === 'mongo',
type: 'boolean',
name: 'ssl',
message: 'Enable SSL connection:',
default: _.get(scope.database, 'ssl', false)
}
])
.then(answers => {
if (hasDatabaseConfig) {
answers = _.merge((_.omit(scope.database.settings, ['client'])), scope.database.options);
2018-05-04 17:50:39 +02:00
}
2018-01-08 12:00:56 +01:00
2018-05-04 17:50:39 +02:00
scope.database.settings.host = answers.host;
2018-08-31 00:47:45 +09:00
scope.database.settings.srv = _.toString(answers.srv) === 'true';
2018-05-04 17:50:39 +02:00
scope.database.settings.port = answers.port;
scope.database.settings.database = answers.database;
scope.database.settings.username = answers.username;
scope.database.settings.password = answers.password;
scope.database.options.authenticationDatabase = answers.authenticationDatabase;
scope.database.options.ssl = _.toString(answers.ssl) === 'true';
2018-01-10 14:45:32 +01:00
2018-06-22 15:25:15 +02:00
console.log();
console.log('⏳ Testing database connection...');
2018-05-04 17:50:39 +02:00
resolve();
});
}),
new Promise(resolve => {
const isStrapiInstalledWithNPM = packageManager.isStrapiInstalledWithNPM();
2018-07-10 11:08:58 +02:00
let packageCmd = packageManager.commands('install --prefix', scope.tmpPath);
2018-06-21 15:07:50 +02:00
// Manually create the temp directory for yarn
if (!isStrapiInstalledWithNPM) {
shell.exec(`mkdir ${scope.tmpPath}`);
2018-06-21 15:07:50 +02:00
}
2018-10-29 18:34:31 +01:00
let cmd = `${packageCmd} ${scope.client.connector}@${scope.strapiPackageJSON.version}`;
2018-05-04 17:50:39 +02:00
if (scope.client.module) {
cmd += ` ${scope.client.module}`;
}
2018-07-11 16:23:14 +02:00
if (scope.client.connector === 'strapi-hook-bookshelf') {
2018-10-29 18:34:31 +01:00
cmd += ` strapi-hook-knex@${scope.strapiPackageJSON.version}`;
2018-07-11 16:23:14 +02:00
scope.additionalsDependencies = ['strapi-hook-knex', 'knex'];
2018-05-04 17:50:39 +02:00
}
exec(cmd, () => {
if (scope.client.module) {
const lock = require(path.join(`${scope.tmpPath}`, '/node_modules/', `${scope.client.module}/package.json`));
2018-05-04 17:50:39 +02:00
scope.client.version = lock.version;
2018-07-11 16:23:14 +02:00
if (scope.developerMode === true && scope.client.connector === 'strapi-hook-bookshelf') {
2018-05-04 17:50:39 +02:00
const knexVersion = require(path.join(`${scope.tmpPath}`,`/node_modules/`,`knex/package.json`));
scope.additionalsDependencies[1] = `knex@${knexVersion.version || 'latest'}`;
}
}
2018-05-04 17:50:39 +02:00
resolve();
});
})
];
2018-01-08 12:00:56 +01:00
2018-05-04 17:50:39 +02:00
Promise.all(asyncFn)
.then(() => {
try {
require(path.join(`${scope.tmpPath}`, '/node_modules/', `${scope.client.connector}/lib/utils/connectivity.js`))(scope, cb.success, connectionValidation);
2018-05-04 17:50:39 +02:00
} catch(err) {
shell.rm('-r', scope.tmpPath);
2018-08-27 14:01:56 +02:00
console.log(err);
cb.error();
2018-05-04 17:50:39 +02:00
}
});
2018-01-08 12:00:56 +01:00
});
};
connectionValidation();
2016-03-18 11:12:50 +01:00
};