ojparty
Version:
OJParty is a lightweight Node.js framework that enhances the default HTTP module by offering Express-like routing with added support for file uploads and session management, making it easy to build web applications without heavy dependencies.
377 lines (340 loc) • 11.2 kB
JavaScript
exports.ojparty = {
utill:{
parseCookie:(data)=>{
var result = {};
if(!data || data == undefined) return
data.split("; ").forEach(v=>{
let keyValue = v.split("=");
result[keyValue[0]] = (keyValue.hasOwnProperty(1))?keyValue[1]:'';
});
return result;
},
range:(min,max)=>{
return Math.floor(Math.random() * (max - min +1) ) + min;
},
random:(type,length)=>{
const num =[0,1,2,3,4,5,6,7,8,9];
const choose = [0,1];
const alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
const mix = ["num","letlower","letupper"];
var result = "";
switch(type){
case "num":
for(let i = 0; i < length; i++){
result += num[exports.ojparty.utill.range(0,(num.length -1))]
}
break;
case "let":
case "letter":
for(let i = 0; i < length; i++){
var c = choose[exports.ojparty.utill.range(0,1)];
if(c)result+=alpha[exports.ojparty.utill.range(0,(alpha.length -1))].toLowerCase()
else result+=alpha[exports.ojparty.utill.range(0,(alpha.length -1))]
}
break;
case "mix":
for(let i = 0; i < length; i++){
var c = mix[exports.ojparty.utill.range(0,2)];
if(c == "letlower")result+=alpha[exports.ojparty.utill.range(0,(alpha.length -1))].toLowerCase()
else if(c == "letupper") result+=alpha[exports.ojparty.utill.range(0,(alpha.length -1))]
else result += num[exports.ojparty.utill.range(0,(num.length -1))]
}
break;
default:
for(let i = 0; i < length; i++){
var c = mix[exports.ojparty.utill.range(0,2)];
if(c == "letlower")result+=alpha[exports.ojparty.utill.range(0,(alpha.length -1))].toLowerCase()
else if(c == "letupper") result+=alpha[utill.range(0,(alpha.length -1))]
else result += num[exports.ojparty.utill.range(0,(num.length -1))]
}
}
return result;
},
writeFile:(path,data)=>{
const fs = require('fs');
const hasPath = (path.split("/").length > 0)?true:false;
if(hasPath && !fs.existsSync(path.split("/").slice(0,-1).join("/"))){
throw "path '"+path.split("/").slice(0,-1).join("/")+"' dose not exists."
}else if(data === undefined){
data = "undefined"
}
fs.writeFile(path, data, (err) => {
if (err) {
return false;
} else {
return true;
}
});
}
},
forms:(req,cb)=>{
const qs = require("querystring")
const actualUrl = (req.hasOwnProperty('url') && req.url !== undefined)?req.url.toString().split("?")[0]:''
const queryString = (req.hasOwnProperty('url') && req.url !== undefined)?req.url.toString().split("?")[1]:{}
query = qs.parse(queryString)
url = actualUrl
if(req.method == "POST"){
var err = false,totalFile = -1;
let bufferData = Buffer.alloc(0);
req.on("data",(ch)=>{
bufferData = Buffer.concat([bufferData,ch]);
});
req.on("end",async ()=>{
var files = [];
var body = {};
var entries = {};
const rct = req.headers['content-type'];
if(rct && rct.toString().match(/multipart\/form-data/i)){
const boundry = "--"+req.headers['content-type'].split("=")[1];
let start = bufferData.indexOf(Buffer.from(boundry))+Buffer.from(boundry).length;
let end = bufferData.indexOf(Buffer.from(boundry),start);
while(end !== -1){
const bufferParts = bufferData.slice(start,end);
let headerEnd = bufferParts.indexOf(Buffer.from("\r\n\r\n"));
const header = bufferParts.slice(0,headerEnd);
const body = bufferParts.slice(headerEnd + 4);
fileName = header.toString().match(/filename="([^"]+)"/);
if(fileName){
files.push({
size:body.length,
file:body,
fileName:fileName[1],
contentType : header.toString().split("Content-Type: ")[1]
})
}else{
entries[header.toString().match(/name="([^"]+)"/)[1]] = body.toString().trim();
}
start = end + Buffer.from(boundry).length;
end = bufferData.indexOf(Buffer.from(boundry),start);
}
body = entries;
}else if(rct && rct.toString().match(/json/i)){
body = JSON.parse(bufferData.toString());
}else if(rct && rct.toString().match(/text/i) || req.headers['content-type'].match(/x-www-form-urlencoded/i)){
try{
body = JSON.parse(bufferData.toString());
}catch(e){
const q = require('querystring');
body = q.parse(bufferData.toString());
}
}else{
body = bufferData.toString();
}
cb({body,files,query,url})
})
}else{
cb({query,url})
}
},
app:()=>{
const imp = {
get:{},
post:{},
delete:{},
options:{},
put:{},
session:{},
settings:{}
}
function addImp(method,path,addImpCb){
imp[method][path] = addImpCb
}
function setSession(key,value,id){
if(key in imp['session'][id]){
imp['session'][id][key] = value;
}else{
imp['session'][id] = {...{[key]:value}}
}
}
function unsetSession(key,id){
if(key in imp['session'][id]){
delete imp['session'][id][key];
}
}
function sendFile(url,res){
const fs = require("fs")
const path = require("path")
try{
const data = fs.readFileSync(path.join(url))
res.statusCode = 200
res.write(data);
res.end()
}catch(e){
throw err
}
}
function serveStatic(req,res){
const fs = require("fs");
const path = require("path");
const filePath = path.join(req.url.slice(1,req.url.length));
var check;
try{
check = fs.statSync(filePath);
}catch(e){
check = false;
}
var data;
if(check && check.isDirectory() || imp.settings.hasOwnProperty('hideFiles') && imp.settings.hideFiles.includes(req.url)){
data = ""
}else if(check){
data = fs.readFileSync(filePath);
}else{
data = '';
if(imp.settings.hasOwnProperty('404') && imp.settings['404'] != ''){
res.ojp(imp.settings['404']);
}
//
}
res.write(Buffer.from(data))
}
function ojp(url,verb,res){
function ojpEx(x){
if(x.slice(2,-1) == "ojp" || x.slice(2,-1) == "/ojp"){
return x;
}else if(x.slice(2,-1) in verb){
switch(typeof verb[x.slice(2,-1)]){
case "object":
return JSON.stringify(verb[x.slice(2,-1)])
break;
default:
return verb[x.slice(2,-1)]
}
} else{
throw "undefined ojp variable '"+x.slice(2,-1)+"' in "+url;
}
}
function ojpInline(x){
var re;
function replaceOut(n) {
var r;
switch (n) {
case "$[ojp]":
r = '`)';
re = true;
break;
case "$[/ojp]":
r = 'sam(`';
re = true;
break;
default:
r = n;
re = false;
}
return r;
}
var ojpR = '',nx;
const sam = (x = '') =>{ojpR += (x && x.length > 0)?x :''; };
a = x.match(/\$\[ojp\]([\s\S]+)(.*?)([\s\S]+)\$\[\/ojp\]/g),
_a = a && a.hasOwnProperty(0) ? a[0].slice(6, -7) : x;
b = _a.replaceAll(/\$\[\/ojp\]/g, replaceOut);
b = b.replaceAll(/\$\[ojp\]/g, replaceOut);
if(b.includes("sam(")){
try{
eval(b)
nx = x.replaceAll(/\$\[ojp\]([\s\S]+)(.*?)([\s\S]+)\$\[\/ojp\]/g, ojpR);
}catch(e){
throw e
}
}else{
nx = x;
}
return nx;
}
var data;
try {
const fs = require("fs");
data = fs.readFileSync(url);
} catch (e) {
throw e;
}
try{
var dataR = ojpInline(data.toString().replaceAll(/\$\[(.*?)\]/g,ojpEx));
res.write(dataR);
}catch(e){
throw e;
}
}
function sql(con,query,entry){
const mysql = require("mysql");
const connect = mysql.createConnection(con);
connect.connect((r)=>{if(r) throw r});
return new Promise((res,rej)=>{
connect.query(query,entry,(err,data)=>{
if(err) { rej(err) }
else { res(data) }
});
connect.end();
});
}
function sendMail(data,debug = false){
}
function settings(x){
imp.settings = x;
}
const run = {
get:(path,appCb)=>addImp('get',path,appCb),
post:(path,appCb)=>addImp('post',path,appCb),
options:(path,appCb)=>addImp('options',path,appCb),
delete:(path,appCb)=>addImp('delete',path,appCb),
settings:(x)=>settings(x),
listen:(port = '',ip = '',cb = ()=>0)=>{
const http = require("http");
server = http.createServer((req,res)=>{
exports.ojparty.forms(req,function(b){
const utill = exports.ojparty.utill;
req.query = b.query
req.files = b.files
req.body = b.body
req.url = b.url
res.sendFile = (path) => sendFile(path,res);
// console.log(req.headers.cookie)
// console.log(utill.parseCookie(req.headers.cookie) && 'OJPSSID' in utill.parseCookie(req.headers.cookie))
//|| req.headers.hasOwnProperty('cookie') && !utill.parseCookie(req.headers.cookie).hasOwnProperty('OJPSSID')
if(!req.headers.hasOwnProperty('cookie') || utill.parseCookie(req.headers.cookie)['OJPSSID'] == undefined){
reqId = utill.random("mix",34);
res.setHeader('Set-Cookie','OJPSSID='+reqId+';HttpOnly;SameSite=Lax');
//console.log('not set')
// console.log(req.method)
}else{
reqId = utill.parseCookie(req.headers.cookie)['OJPSSID'];
// console.log('already set')
// console.log(req.method)
}
if(!imp['session'].hasOwnProperty(reqId)){
imp['session'][reqId] = {};
}
req.setSession = (key,value)=>setSession(key,value,reqId)
req.unsetSession = (key)=>unsetSession(key,reqId)
req.moveUploadedFile = (path,data) => utill.writeFile(path,data)
req.sql = (con,query,entry = [])=>sql(con,query,entry);
res.ojp = (path, verb = {})=>ojp(path,verb,res);
res.sendMail = (data,debug=false) => sendMail(data,debug);
res.send = (data)=>{
res.statusCode = 200;
res.write(Buffer.from(data));
res.end();
}
const {method,url} = req;
calls = (method.toLocaleLowerCase() in imp && url.toString() in imp[method.toLocaleLowerCase()])? imp[method.toLocaleLowerCase()][url]:false;
req.session = imp['session'][reqId];
if(calls){
calls(req,res)
}else if(!calls && imp.settings.hasOwnProperty('serveStatic') && imp.settings.serveStatic== true){
serveStatic(req,res)
res.end();
}else{
res.statusCode = 200;
res.write(`Can not get ${url}`)
res.end()
}
});
});
port = (port != '' && typeof port == "number")?port:'';
cb = (typeof ip == "function")?ip:cb;
if(port == '') server.listen()
else server.listen(port,ip,cb)
}
};
return run;
}
}