UNPKG

jserver

Version:

A toolkit that automatically generates APIs based on JSON or DATABASE.

338 lines (282 loc) 10.6 kB
#!/usr/bin/env node 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(); }