多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

292 lines
8.9 KiB

import chalkPipe from 'chalk-pipe';
import inquirer from 'inquirer';
import tcpPortUsed from 'tcp-port-used';
import URL from 'url';
import Util from "../util/Util";
import path from 'path';
import Lang, {STR} from "../util/Lang";
import('colors');
const dbDefaults = {
mysql2: {
host: 'localhost',
port: '3306',
username: 'root',
password: '',
database: ''
},
pg: {
host: 'localhost',
port: '5432',
username: 'postgres',
password: '',
database: ''
},
mssql: {
host: 'localhost',
port: '1433',
username: 'sa',
password: '',
database: ''
},
sqlite3: {
host: 'localhost',
port: '1433',
username: 'sa',
password: '',
database: ''
},
};
class TryMgr {
/**
*
* Does the below :
* - Get database input and make a DB URL from it.
* - Create new folder and 'cd' to that folder.
* - Return true/success
* - Else failure
*
* @param args
* @returns {Promise<string|string|boolean|*>}
*/
public static async getProjectInput(args): Promise<any> {
let dbUrl;
if (args._[0] !== 't' && args._[0] !== 'try') {
if ( args._[1] === 'rest') {
dbUrl = `sqlite3://sqlite3?d=${path.join(__dirname, 'sakila.db')}`;
} else if (args._[1] === 'gql') {
dbUrl = `sqlite3://sqlite3?d=${path.join(__dirname, 'sakila.db')}&api=graphql`;
}
} else {
/* Construct database URL from prompt */
const dbTypes = Object.keys(dbDefaults);
args.url = []
const finalAnswers = await inquirer
.prompt([
{
name: 'type',
type: 'list',
message: Lang.getString(STR.DB_TYPE),// '🔥 Choose SQL Database type\t:',
choices: dbTypes.map(t => ({
name: t,
value: t,
short: t.green.bold
})),
default: 'mysql2',
transformer(color) {
return chalkPipe(color)(color.green.bold);
}
},
{
name: 'host',
type: 'input',
message: Lang.getString(STR.DB_HOST),// '👉 Enter database host name\t:',
default(ans) {
return dbDefaults[ans.type].host
},
transformer(color) {
return chalkPipe(color)(color.green.bold);
},
when({type}) {
return type !== 'sqlite3'
}
},
{
name: 'port',
type: 'number',
message: Lang.getString(STR.DB_PORT),// '👉 Enter database port number\t:',
default(ans) {
return dbDefaults[ans.type].port
},
transformer(color) {
try {
return color.green.bold;
} catch (e) {
return color
}
},
validate(port, answers) {
const done = this.async();
if (answers.host === 'host.docker.internal' || answers.host === 'docker.for.win.localhost') {
done(null, true)
} else {
TryMgr.isPortOpen(answers.host, port).then(isOpen => {
if (isOpen) {
done(null, true)
} else {
// done('Port is not open')
console.log(`\n\n😩 ${answers.host}:${port} is not open please start the database if you haven't\n`.red.bold)
process.exit(0);
}
}).catch(done)
}
},
when({type}) {
return type !== 'sqlite3'
}
},
{
name: 'username',
type: 'input',
message: Lang.getString(STR.DB_USER), // '👉 Enter database username\t:',
default(ans) {
return dbDefaults[ans.type].username
},
transformer(color) {
return chalkPipe(color)(color.green.bold);
},
when({type}) {
return type !== 'sqlite3'
}
},
{
name: 'password',
type: 'input',
mask: true,
message: Lang.getString(STR.DB_PASSWORD), // '🙈 Enter database password\t:',
transformer(color) {
return new Array(color.length).fill('*'.green.bold).join('')
},
when({type}) {
return type !== 'sqlite3'
}
},
{
name: 'database',
type: 'input',
message: Lang.getString(STR.DB_SCHEMA), // '👉 Enter database/schema name\t:',
transformer(color) {
return chalkPipe(color)(color.green.bold);
},
when({type}) {
return type !== 'sqlite3'
}
},
{
name: 'apiType',
type: 'list',
message: Lang.getString(STR.DB_API), // '🚀 Enter API type to generate\t:',
choices: ['REST APIs', 'GRAPHQL APIs', 'gRPC APIs'].map(t => ({
name: t,
value: t,
short: t.green.bold
})),
transformer(color) {
return chalkPipe(color)(color.green.bold);
},
when({type}) {
return type !== 'sqlite3'
}
},
])
// console.log(finalAnswers);
if (finalAnswers.type === 'sqlite3') {
console.log('Please use desktop app to create Sqlite project'.green.bold)
process.exit(0);
}
/* if not valid retry getting right input */
/* if (!finalAnswers.database) {
console.log('\n\tWarning! Database name can NOT be empty. Retry.\n '.red.bold);
this.getNewProjectInput(args);
}*/
//
/* prepare the args */
// const url = `${finalAnswers.type}://${finalAnswers.host}:${finalAnswers.port}?u=${finalAnswers.username}&p=${finalAnswers.password}&d=${finalAnswers.database}&api=${apiTypeMapping[finalAnswers.projectType]}`;
// args._[0] = finalAnswers.projectType === 'REST APIs' ? 'gar' : 'gag';
switch (finalAnswers.apiType) {
case 'REST APIs':
finalAnswers.apiType = 'rest';
break;
case 'GRAPHQL APIs':
finalAnswers.apiType = 'graphql';
break;
case 'gRPC APIs':
finalAnswers.apiType = 'grpc';
break;
default:
finalAnswers.apiType = 'rest';
break;
}
dbUrl = `${finalAnswers.type}://${finalAnswers.host}:${finalAnswers.port}?u=${finalAnswers.username}&p=${finalAnswers.password}&d=${finalAnswers.database}&api=${finalAnswers.apiType}`
}
// await Util.runCmd(`cd ${__dirname};echo "const {XcTry} = require('xc-instant'); process.env.NC_DB_URL='${finalAnswers.dbUrl}'; XcTry().then(() => console.log('App started'));" | node`);
await Util.runCmd(`echo "const {XcTry} = require('xc-instant'); XcTry('${dbUrl}').then(() => console.log('App started'));" | NODE_PATH=${path.join(__dirname, '..', 'node_modules')} node`);
}
public static async testConnection({url}) {
for (const u of url) {
const parsedUrlData = URL.parse(u, true);
const queryParams = parsedUrlData.query;
const client = parsedUrlData.protocol.slice(0, -1);
const config = {
client,
connection: {
database: client === 'pg' ? 'postgres' : (client === 'mssql' ? undefined : null),
host: parsedUrlData.hostname,
password: queryParams.p,
port: +parsedUrlData.port,
user: queryParams.u,
}
};
try {
const knex = require('knex')(config)
await knex.raw("SELECT 1+1 as data");
} catch (e) {
console.log(`\n😩 Test connection failed for : ${url}\n`.red.bold)
return false;
}
}
return true;
}
public static async isPortOpen(host, port) {
try {
return await tcpPortUsed.check(+port, host)
} catch (e) {
console.log(e)
console.log(`\n😩 ${host}:${port} is not reachable please check\n`.red.bold)
return true;
}
}
}
export default TryMgr;
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/