jserver
Version:
A toolkit that automatically generates APIs based on JSON or DATABASE.
338 lines (282 loc) • 10.6 kB
JavaScript
const express = require('express');
const fileUpload = require('express-fileupload');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const fs = require('fs');
const os = require('os');
const args = require('minimist')(process.argv.slice(2))
if (args.help) {
console.log(`
Title: A toolkit that automatically generates APIs based on JSON or DATABASE.
Version: 1.3.6.
Params: [
--help: Displays this help message.
--version: Displays the version of the toolkit.
--mode: The mode to run the toolkit in. ['json', 'database'] default = json.
--file: The path to the JSON file. default = db.json.
--upload: The path to the upload folder. default = /files.
--port: The port to run the server on. default = 3000.
--host: The host to connect to the database. default = 127.0.0.1.
--dport: The dport to connect to the database. default = 3306.
--user: The user to connect to the database. default = root.
--password: The password to connect to the database. default = 123456.
--database: The database to connect to the database. default = db.
]
`);
process.exit(1);
}
if (args.version) {
console.log(`v1.3.6`);
process.exit(1);
}
const ipv4AddressEntries = Object.values(os.networkInterfaces()).reduce((x, y) => x.concat(y)).filter(e => e.family === 'IPv4').map(e => e.address);
const apis = []
const envs = {
filePath: args.file?.toString() || 'db.json',
port: args.port || 3000,
upload: args.upload === undefined ? '/files' : args.upload,
}
if (typeof envs.port !== "number") {
console.error('Error: Port must be a number');
process.exit(1);
}
if (envs.port <= 1024 || envs.port >= 65535) {
console.error('Error: Port must be between 1024 and 65535');
process.exit(1);
}
let currentDir = '';
envs.upload = envs.upload === '' || envs.upload === '/' ? '' : envs.upload.startsWith('/') ? envs.upload : '/' + envs.upload
const fileArray = ('public' + envs.upload).split('/')
const app = express();
app.use(express.static('public'));
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(fileUpload());
app.all('*', (req, res, next) => {
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader("Content-Type", "application/json;charset=utf-8");
next();
})
app.get('/upload-template', (req, res) => {
res.setHeader("Content-Type", "text/html;charset=utf-8");
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>upload template</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="upload">
</form>
</body>
</html>
`)
})
app.post('/upload', (req, res) => {
if (req.files && Object.keys(req.files).length !== 0) {
const file = req.files.file;
const filePath = `${envs.upload}/${file.md5 + '.' + file.name.split(/\.(?=[^\.]+$)/)[1]}`;
fileArray.forEach(e => {
currentDir += e + '/'
if (!fs.existsSync(currentDir)) {
fs.mkdirSync(currentDir)
}
})
currentDir = ''
file.mv('public' + filePath, (err) => {
if (err) {
res.send({
code: 500,
msg: 'File upload failed',
data: null
});
} else {
res.send({
code: 200,
msg: 'success',
data: filePath
});
}
});
} else {
res.send({
code: 403,
msg: 'No file uploaded',
data: null
});
}
})
function dbMain() {
const config = {
host: args.host?.toString() || '127.0.0.1',
port: args.dport || 3306,
user: args.user?.toString() || 'root',
password: args.password?.toString() || '123456',
database: args.database?.toString() || 'db'
}
const connection = mysql.createConnection(config);
connection.connect((err) => {
if (err) {
console.error('Error connecting to database:', err.sqlMessage);
process.exit(1);
}
});
connection.query('show tables', (err, result) => {
if (err) {
console.error('Error querying database:', err.sqlMessage);
process.exit(1);
}
result.map(e => Object.values(e)[0]).forEach(table => {
apis.push(`${table} http://127.0.0.1:${envs.port}/${table}`);
app.get(`/${table}`, (req, res) => {
const page = req.query.page || 1;
const limit = req.query.limit || 10;
const query = Object.fromEntries(Object.entries(req.query).filter(([key]) => key !== 'limit' && key !== 'page'));
connection.query(`SELECT * FROM ${table} WHERE ` + (Object.entries(query).map(([key, value]) => `\`${key}\` = '${value}'`).join(' and ') || 1) + ` LIMIT ${(page - 1) * limit}, ${limit}`, (err, result) => {
if (err) {
res.send({
code: 500,
msg: err.sqlMessage,
data: null
});
return;
}
res.send({
code: 200,
msg: 'success',
data: result
});
});
});
app.get(`/${table}/delete`, (req, res) => {
connection.query(`DELETE FROM ${table} WHERE ` + (Object.entries(req.query).map(([key, value]) => `\`${key}\` = '${value}'`).join(' and ') || 1), (err, result) => {
if (err) {
res.send({
code: 500,
msg: err.sqlMessage,
data: null
});
return;
}
res.send({
code: 200,
msg: 'success',
data: true
});
});
});
app.post(`/${table}/create`, (req, res) => {
connection.query(`INSERT INTO ${table} (${Object.keys(req.body).map(e => `\`${e}\``).join(', ')}) VALUES (${Object.values(req.body).map(e => `'${e}'`).join(', ')})`, (err, result) => {
if (err) {
res.send({
code: 500,
msg: err.sqlMessage,
data: null
});
return;
}
res.send({
code: 200,
msg: 'success',
data: true
});
});
});
app.post(`/${table}/update`, (req, res) => {
connection.query(`UPDATE ${table} SET ` + Object.entries(req.body).map(([key, value]) => `\`${key}\` = '${value}'`).join(', ') + ` WHERE ` + (Object.entries(req.query).map(([key, value]) => `\`${key}\` = '${value}'`).join(' and ') || 1), (err, result) => {
if (err) {
res.send({
code: 500,
msg: err.sqlMessage,
data: null
});
return;
}
res.send({
code: 200,
msg: 'success',
data: true
});
});
});
app.get(`/${table}/count`, (req, res) => {
connection.query(`SELECT COUNT(*) FROM ${table} WHERE ` + (Object.entries(req.query).map(([key, value]) => `\`${key}\` = '${value}'`).join(' and ') || 1), (err, result) => {
if (err) {
res.send({
code: 500,
msg: err.sqlMessage,
data: null
});
return;
}
res.send({
code: 200,
msg: 'success',
data: result[0]['COUNT(*)']
});
});
});
});
app.listen(envs.port, () => {
console.log(`
Server is running on port ${envs.port}
♡⸜(˶˃ ᵕ ˂˶)⸝♡
Available Networks:
${ipv4AddressEntries.map(entry => `http://${entry}:${envs.port}/`).join('\n')}
Available APIs:
${apis.join('\n')}
`);
});
});
}
function main() {
if (typeof args._[0] === "string") {
envs.filePath = args._[0];
}
if (envs.filePath.split('.')[1] !== 'json') {
console.error('Error: File must be a JSON file');
process.exit(1);
}
try {
var file = fs.readFileSync(envs.filePath, {
encoding: 'utf-8'
});
} catch (e) {
console.error('File not found');
process.exit(1);
}
try {
var entries = Object.entries(JSON.parse(file.toString()));
} catch (e) {
console.error('File is not a valid JSON file');
process.exit(1);
}
entries.forEach(([key, value]) => {
apis.push(`${key} http://127.0.0.1:${envs.port}/${key}`);
app.get(`/${key}`, (req, res) => {
res.send(value);
});
});
app.listen(envs.port, () => {
console.log(`
Server is running on port ${envs.port}
♡⸜(˶˃ ᵕ ˂˶)⸝♡
Available Networks:
${ipv4AddressEntries.map(entry => `http://${entry}:${envs.port}/`).join('\n')}
Available APIs:
${apis.join('\n')}
`);
});
}
if (args.mode === 'database') {
dbMain();
} else {
main();
}