mirror of https://github.com/nocodb/nocodb
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
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/>. |
|
* |
|
*/
|
|
|