2022-04-17 10:00:42 +08:00
|
|
|
const chalk = require('chalk');
|
|
|
|
const fse = require('fs-extra');
|
|
|
|
const path = require('path');
|
|
|
|
const { hasYarn, runInit, runInstall } = require('./utils');
|
|
|
|
const ora = require('ora');
|
|
|
|
const execa = require('execa');
|
|
|
|
const { join, resolve } = require('path');
|
|
|
|
|
|
|
|
const createEnvFile = require('./resources/templates/env');
|
|
|
|
const createPackageJson = require('./resources/templates/package.json.js');
|
|
|
|
const createServerPackageJson = require('./resources/templates/server.package.json.js');
|
|
|
|
const loadSrcFromNpm = require('./resources/templates/load-src-from-npm');
|
|
|
|
|
2022-04-20 23:36:05 +08:00
|
|
|
let envs = undefined;
|
|
|
|
|
|
|
|
const parseEnvs = (options) => {
|
|
|
|
if (envs) {
|
|
|
|
return envs;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const env of options.env) {
|
|
|
|
if (!env.match(/\w+=\w+/)) {
|
|
|
|
console.log(`${chalk.red(env)} is not a valid environment value`);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
envs = options.env
|
|
|
|
.map((env) => env.split('='))
|
|
|
|
.reduce((carry, item) => {
|
|
|
|
carry[item[0]] = item[1];
|
|
|
|
return carry;
|
|
|
|
}, {});
|
|
|
|
|
|
|
|
return envs;
|
|
|
|
};
|
|
|
|
|
|
|
|
function checkDialect(dialect) {
|
|
|
|
const supportDialects = ['mysql', 'sqlite', 'postgres'];
|
|
|
|
if (!supportDialects.includes(dialect)) {
|
|
|
|
console.log(
|
|
|
|
`dialect ${chalk.red(dialect)} is not supported, currently supported dialects are ${chalk.green(
|
|
|
|
supportDialects.join(','),
|
|
|
|
)}.`,
|
|
|
|
);
|
|
|
|
process.exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-17 10:00:42 +08:00
|
|
|
const getDatabaseOptionsFromCommandOptions = (commandOptions) => {
|
2022-04-20 23:36:05 +08:00
|
|
|
const envs = parseEnvs(commandOptions);
|
|
|
|
|
|
|
|
if (!commandOptions.dbDialect || commandOptions.dbDialect === 'sqlite' || envs['DB_STORAGE']) {
|
2022-04-17 10:00:42 +08:00
|
|
|
return {
|
|
|
|
dialect: 'sqlite',
|
2022-04-20 23:36:05 +08:00
|
|
|
storage: envs['DB_STORAGE'] || 'db.sqlite',
|
2022-04-17 10:00:42 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-04-20 23:36:05 +08:00
|
|
|
const databaseOptions = {
|
|
|
|
dialect: commandOptions.dbDialect,
|
|
|
|
host: envs['DB_HOST'],
|
|
|
|
port: envs['DB_PORT'],
|
|
|
|
database: envs['DB_DATABASE'],
|
2022-04-21 10:56:29 +08:00
|
|
|
user: envs['DB_USER'],
|
2022-04-20 23:36:05 +08:00
|
|
|
password: envs['DB_PASSWORD'],
|
2022-04-17 10:00:42 +08:00
|
|
|
};
|
2022-04-20 23:36:05 +08:00
|
|
|
|
|
|
|
const emptyValues = Object.entries(databaseOptions).filter((items) => !items[1]);
|
|
|
|
|
|
|
|
if (emptyValues.length > 0) {
|
|
|
|
console.log(
|
|
|
|
chalk.red(
|
|
|
|
`Please set ${emptyValues
|
|
|
|
.map((i) => i[0])
|
|
|
|
.map((i) => `DB_${i.toUpperCase()}`)
|
|
|
|
.join(' ')} in .env file to complete database settings`,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return databaseOptions;
|
2022-04-17 10:00:42 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
async function createApp(directory, options) {
|
2022-04-20 23:36:05 +08:00
|
|
|
const dbDialect = options.dbDialect || 'sqlite';
|
|
|
|
checkDialect(dbDialect);
|
|
|
|
|
|
|
|
if (options.quickstart) {
|
|
|
|
console.log(`⚠️ ${chalk.yellow('quickstart option is deprecated')}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
parseEnvs(options);
|
|
|
|
|
2022-04-17 10:00:42 +08:00
|
|
|
console.log(`Creating a new NocoBase application at ${chalk.green(directory)}.`);
|
|
|
|
console.log('Creating files.');
|
|
|
|
|
|
|
|
const projectPath = path.join(process.cwd(), directory);
|
|
|
|
const resourcePath = path.join(__dirname, 'resources');
|
|
|
|
|
|
|
|
const dbOptions = getDatabaseOptionsFromCommandOptions(options);
|
|
|
|
|
|
|
|
// copy files
|
|
|
|
await fse.copy(path.join(resourcePath, 'files'), projectPath);
|
|
|
|
|
|
|
|
console.log('download @nocobase/app-server');
|
|
|
|
await loadSrcFromNpm('@nocobase/app-server', path.join(projectPath, 'packages/app/server'));
|
|
|
|
|
|
|
|
console.log('download @nocobase/app-client');
|
|
|
|
await loadSrcFromNpm('@nocobase/app-client', path.join(projectPath, 'packages/app/client'));
|
|
|
|
|
|
|
|
// write .env file
|
2022-04-20 23:36:05 +08:00
|
|
|
await fse.writeFile(join(projectPath, '.env'), createEnvFile({ dbOptions, envs: parseEnvs(options) }));
|
2022-04-17 10:00:42 +08:00
|
|
|
|
|
|
|
// write root packages.json
|
|
|
|
await fse.writeJson(
|
|
|
|
join(projectPath, 'package.json'),
|
|
|
|
createPackageJson({
|
|
|
|
projectName: 'nocobase-app',
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
spaces: 2,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
// write server package.json
|
|
|
|
await fse.writeJson(
|
|
|
|
join(projectPath, 'packages/app/server/package.json'),
|
|
|
|
createServerPackageJson({
|
|
|
|
projectPath,
|
|
|
|
dbOptions,
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
spaces: 2,
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
// run install command
|
2022-04-20 23:36:05 +08:00
|
|
|
console.log('finished');
|
|
|
|
}
|
|
|
|
|
|
|
|
function collect(value, previous) {
|
|
|
|
return previous.concat([value]);
|
2022-04-17 10:00:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
function setCommandOptions(command) {
|
|
|
|
return command
|
|
|
|
.arguments('<directory>', 'directory of new NocoBase app')
|
|
|
|
.option('--quickstart', 'Quickstart app creation')
|
2022-04-20 23:36:05 +08:00
|
|
|
.option('-d, --db-dialect <dbdialect>', 'Database dialect, current support sqlite/mysql/postgres')
|
|
|
|
.option('-e, --env <envvalue>', 'environment variables write into .env file', collect, [])
|
2022-04-17 10:00:42 +08:00
|
|
|
.description('create a new application');
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
setCommandOptions,
|
|
|
|
createApp,
|
|
|
|
};
|