Fix create nocobase app (#305)

* chore: create-nocobase-app

* chore: change create-nocobase-app lib to src
This commit is contained in:
ChengLei Shao 2022-04-20 23:36:05 +08:00 committed by GitHub
parent 446437cea7
commit c940873ec8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 96 additions and 28 deletions

View File

@ -7,7 +7,7 @@
"packages/plugins/*" "packages/plugins/*"
], ],
"scripts": { "scripts": {
"start": "concurrently \"npm run start-server\" \"npm run start-client\"", "start": "concurrently --kill-others \"npm run start-server\" \"npm run start-client\"",
"start-pm2": "yarn pm2-runtime start packages/app/server/lib/index.js", "start-pm2": "yarn pm2-runtime start packages/app/server/lib/index.js",
"start-docs": "dumi dev", "start-docs": "dumi dev",
"bootstrap": "lerna bootstrap", "bootstrap": "lerna bootstrap",

View File

@ -1,3 +1,3 @@
#!/usr/bin/env node #!/usr/bin/env node
require('../lib/create-nocobase-app'); require('../src/create-nocobase-app');

View File

@ -1,7 +1,7 @@
{ {
"name": "create-nocobase-app", "name": "create-nocobase-app",
"version": "0.6.2-alpha.8", "version": "0.6.2-alpha.8",
"main": "lib/index.js", "main": "src/index.js",
"files": [ "files": [
"lib", "lib",
"bin", "bin",

View File

@ -11,30 +11,87 @@ const createPackageJson = require('./resources/templates/package.json.js');
const createServerPackageJson = require('./resources/templates/server.package.json.js'); const createServerPackageJson = require('./resources/templates/server.package.json.js');
const loadSrcFromNpm = require('./resources/templates/load-src-from-npm'); const loadSrcFromNpm = require('./resources/templates/load-src-from-npm');
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);
}
}
const getDatabaseOptionsFromCommandOptions = (commandOptions) => { const getDatabaseOptionsFromCommandOptions = (commandOptions) => {
if ( const envs = parseEnvs(commandOptions);
commandOptions.quickstart ||
!commandOptions.dbdialect || if (!commandOptions.dbDialect || commandOptions.dbDialect === 'sqlite' || envs['DB_STORAGE']) {
commandOptions.dbdialect === 'sqlite' ||
commandOptions.dbstorage
) {
return { return {
dialect: 'sqlite', dialect: 'sqlite',
storage: commandOptions.dbstorage || 'db.sqlite', storage: envs['DB_STORAGE'] || 'db.sqlite',
}; };
} }
return { const databaseOptions = {
dialect: commandOptions.dbdialect, dialect: commandOptions.dbDialect,
host: commandOptions.dbhost, host: envs['DB_HOST'],
port: commandOptions.dbport, port: envs['DB_PORT'],
database: commandOptions.dbdatabase, database: envs['DB_DATABASE'],
username: commandOptions.dbusername, username: envs['DB_USERNAME'],
password: commandOptions.dbpassword, password: envs['DB_PASSWORD'],
}; };
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;
}; };
async function createApp(directory, options) { async function createApp(directory, options) {
const dbDialect = options.dbDialect || 'sqlite';
checkDialect(dbDialect);
if (options.quickstart) {
console.log(`⚠️ ${chalk.yellow('quickstart option is deprecated')}`);
}
parseEnvs(options);
console.log(`Creating a new NocoBase application at ${chalk.green(directory)}.`); console.log(`Creating a new NocoBase application at ${chalk.green(directory)}.`);
console.log('Creating files.'); console.log('Creating files.');
@ -53,7 +110,7 @@ async function createApp(directory, options) {
await loadSrcFromNpm('@nocobase/app-client', path.join(projectPath, 'packages/app/client')); await loadSrcFromNpm('@nocobase/app-client', path.join(projectPath, 'packages/app/client'));
// write .env file // write .env file
await fse.writeFile(join(projectPath, '.env'), createEnvFile({ dbOptions })); await fse.writeFile(join(projectPath, '.env'), createEnvFile({ dbOptions, envs: parseEnvs(options) }));
// write root packages.json // write root packages.json
await fse.writeJson( await fse.writeJson(
@ -79,19 +136,19 @@ async function createApp(directory, options) {
); );
// run install command // run install command
console.log('finished');
}
function collect(value, previous) {
return previous.concat([value]);
} }
function setCommandOptions(command) { function setCommandOptions(command) {
return command return command
.arguments('<directory>', 'directory of new NocoBase app') .arguments('<directory>', 'directory of new NocoBase app')
.option('--quickstart', 'Quickstart app creation') .option('--quickstart', 'Quickstart app creation')
.option('--dbdialect <dbdialect>', 'Database dialect, current support sqlite/mysql/postgres') .option('-d, --db-dialect <dbdialect>', 'Database dialect, current support sqlite/mysql/postgres')
.option('--dbhost <dbhost>', 'Database host') .option('-e, --env <envvalue>', 'environment variables write into .env file', collect, [])
.option('--dbport <dbport>', 'Database port')
.option('--dbdatabase <dbdatabase>', 'Database name')
.option('--dbusername <dbusername>', 'Database username')
.option('--dbpassword <dbpassword>', 'Database password')
.option('--dbstorage <dbstorage>', 'Database file storage path for sqlite')
.description('create a new application'); .description('create a new application');
} }

View File

@ -6,7 +6,7 @@ const _ = require('lodash');
const generateASecret = () => crypto.randomBytes(256).toString('base64'); const generateASecret = () => crypto.randomBytes(256).toString('base64');
module.exports = (options) => { module.exports = (options) => {
const { dbOptions } = options; const { dbOptions, envs } = options;
const tmpl = fs.readFileSync(path.join(__dirname, 'env.template')); const tmpl = fs.readFileSync(path.join(__dirname, 'env.template'));
const compile = _.template(tmpl); const compile = _.template(tmpl);
@ -15,10 +15,20 @@ module.exports = (options) => {
.map((item) => `${item[0]}=${item[1] || ''}`) .map((item) => `${item[0]}=${item[1] || ''}`)
.join('\n'); .join('\n');
const envContent = compile({ let envContent = compile({
jwtSecret: generateASecret(), jwtSecret: generateASecret(),
dbEnvs, dbEnvs,
}); });
for (const env of Object.entries(envs)) {
const [key, value] = env;
const re = new RegExp(`${key}=\\w+`);
if (envContent.match(re)) {
envContent = envContent.replace(re, `${key}=${value}`);
} else {
envContent = `${envContent}${key}=${value}\n`;
}
}
return envContent; return envContent;
}; };

View File

@ -7,7 +7,7 @@ module.exports = (opts) => {
workspaces: ['packages/app/*', 'packages/plugins/*'], workspaces: ['packages/app/*', 'packages/plugins/*'],
license: 'MIT', license: 'MIT',
scripts: { scripts: {
start: 'concurrently "npm run start-server" "npm run start-client"', start: 'concurrently --kill-others "npm run start-server" "npm run start-client"',
bootstrap: 'lerna bootstrap', bootstrap: 'lerna bootstrap',
clean: 'rimraf -rf packages/{app,plugins}/*/{lib,esm,dist} && lerna clean', clean: 'rimraf -rf packages/{app,plugins}/*/{lib,esm,dist} && lerna clean',
nocobase: nocobase:

View File

@ -15,6 +15,7 @@ const dialectLib = (dialect) => {
if (dialect === 'postgres') { if (dialect === 'postgres') {
return { return {
pg: '^8.7.3', pg: '^8.7.3',
'pg-hstore': '^2.3.4',
}; };
} }
}; };