diff --git a/index.js b/index.js index 34b8487..6ff4eb1 100644 --- a/index.js +++ b/index.js @@ -1,16 +1,18 @@ -const Server = require('./src/server/index.js'); -const bodyparser = require('./src/server/body-parser/middleware.js'); -const Router = require('./src/server/router/router.js'); -const route = require('./src/server/router/route.js'); -const {generate} = require('./src/server/middleware-tools/gen.js'); +const Server = require("./src/server.js"); +const bp = require("./src/utils/middleware/body-parser.js"); +const Router = require("./src/utils/router/router.js"); +const route = require("./src/utils/router/route.js"); +const {generate, genAsync} = require("./src/utils/middleware/middleware.js"); +const cors = require("./tools/cors.js"); module.exports = { Server: Server, - bodyparser: bodyparser, + bodyparser: bp, Router: Router, route: route, generateMiddleware: generate, + genMiddlewareAsync: genAsync, tools: { - cors: require('./tools/cors.js') + cors: cors } -}; \ No newline at end of file +}; diff --git a/lib/file-type.js b/lib/file-type.js deleted file mode 100644 index ef3711b..0000000 --- a/lib/file-type.js +++ /dev/null @@ -1,660 +0,0 @@ -// https://en.wikipedia.org/wiki/List_of_file_signatures -// https://github.com/sindresorhus/file-type/blob/master/core.js - -function fromBuffer(buff) { - const arr = Array.from(buff); - function check(testArr, options = {}) { - let offset = 0; - if ("offset" in options) - offset = options.offset; - for (let i in testArr) - if (testArr[i] != arr[+i + offset] || testArr[i] == '?') - return false; - return true; - } - function checkString(str) { - return check(Array.from(Buffer.from(str))); - } - if (check([0x42, 0x4D])) { - return { - ext: 'bmp', - mime: 'image/bmp' - }; - } - - if (check([0x0B, 0x77])) { - return { - ext: 'ac3', - mime: 'audio/vnd.dolby.dd-raw' - }; - } - - if (check([0x78, 0x01])) { - return { - ext: 'dmg', - mime: 'application/x-apple-diskimage' - }; - } - - if (check([0x4D, 0x5A])) { - return { - ext: 'exe', - mime: 'application/x-msdownload' - }; - } - - if (check([0x1F, 0xA0]) || check([0x1F, 0x9D])) { - return { - ext: 'Z', - mime: 'application/x-compress' - }; - } - - if (check([0xFF, 0xD8, 0xFF])) { - return { - ext: 'jpg', - mime: 'image/jpeg' - }; - } - - if (check([0x49, 0x49, 0xBC])) { - return { - ext: 'jxr', - mime: 'image/vnd.ms-photo' - }; - } - - if (check([0x1F, 0x8B, 0x8])) { - return { - ext: 'gz', - mime: 'application/gzip' - }; - } - - if (check([0x42, 0x5A, 0x68])) { - return { - ext: 'bz2', - mime: 'application/x-bzip2' - }; - } - - if (checkString('ID3')) { - return { - ext: 'mp3', - mime: 'audio/mpeg' - }; - } - if (checkString('MP+')) { - return { - ext: 'mpc', - mime: 'audio/x-musepack' - }; - } - - if ((arr[0] == 0x43 || arr[0] == 0x46) && check([0x57, 0x53], { offset: 1 })) { - return { - ext: 'swf', - mime: 'application/x-shockwave-flash' - }; - } - - if (check([0x47, 0x49, 0x46])) { - return { - ext: 'gif', - mime: 'image/gif' - }; - } - - if (checkString('FLIF')) { - return { - ext: 'flif', - mime: 'image/flif' - }; - } - - if (checkString('8BPS')) { - return { - ext: 'psd', - mime: 'image/vnd.adobe.photoshop' - }; - } - - if (checkString('WEBP', { offset: 8 })) { - return { - ext: 'webp', - mime: 'image/webp' - }; - } - - if (checkString('MPCK')) { - return { - ext: 'mpc', - mime: 'audio/x-musepack' - }; - } - - if (checkString('FORM')) { - return { - ext: 'aif', - mime: 'audio/aiff' - }; - } - - if (checkString('icns')) { - return { - ext: 'icns', - mime: 'image/icns' - }; - } - - if (check([0x50, 0x4B, 0x3, 0x4])) { - return { - ext: 'zip', - mime: 'application/zip' - }; - } - - if (checkString('OggS')) { - return { - ext: 'ogx', - mime: 'application/ogg' - }; - } - - if (check([0x50, 0x4B]) && (arr[2] == 0x3 || arr[2] == 0x5 || arr[2] == 0x7) && (arr[3] == 0x4 || arr[3] == 0x6 || arr[3] == 0x8)) { - return { - ext: 'zip', - mime: 'application/zip' - }; - } - - if ( - checkString('ftyp', { offset: 4 }) && - (arr[8] & 0x60) != 0x00 - ) { - const brandMajor = Buffer.from(arr).toString('binary', 8, 12).replace('\0', ' ').trim(); - switch (brandMajor) { - case 'avif': - return { ext: 'avif', mime: 'image/avif' }; - case 'mif1': - return { ext: 'heic', mime: 'image/heif' }; - case 'msf1': - return { ext: 'heic', mime: 'image/heif-sequence' }; - case 'heic': - case 'heix': - return { ext: 'heic', mime: 'image/heic' }; - case 'hevc': - case 'hevx': - return { ext: 'heic', mime: 'image/heic-sequence' }; - case 'qt': - return { ext: 'mov', mime: 'video/quicktime' }; - case 'M4V': - case 'M4VH': - case 'M4VP': - return { ext: 'm4v', mime: 'video/x-m4v' }; - case 'M4P': - return { ext: 'm4p', mime: 'video/mp4' }; - case 'M4B': - return { ext: 'm4b', mime: 'audio/mp4' }; - case 'M4A': - return { ext: 'm4a', mime: 'audio/x-m4a' }; - case 'F4V': - return { ext: 'f4v', mime: 'video/mp4' }; - case 'F4P': - return { ext: 'f4p', mime: 'video/mp4' }; - case 'F4A': - return { ext: 'f4a', mime: 'audio/mp4' }; - case 'F4B': - return { ext: 'f4b', mime: 'audio/mp4' }; - case 'crx': - return { ext: 'cr3', mime: 'image/x-canon-cr3' }; - default: - if (brandMajor.startsWith('3g')) { - if (brandMajor.startsWith('3g2')) { - return { ext: '3g2', mime: 'video/3gpp2' }; - } - - return { ext: '3gp', mime: 'video/3gpp' }; - } - - return { ext: 'mp4', mime: 'video/mp4' }; - } - } - - if (checkString('MThd')) { - return { - ext: 'mid', - mime: 'audio/midi' - }; - } - - if ( - checkString('wOFF') && - ( - check([0x00, 0x01, 0x00, 0x00], { offset: 4 }) || - checkString('OTTO', { offset: 4 }) - ) - ) { - return { - ext: 'woff', - mime: 'font/woff' - }; - } - - if ( - checkString('wOF2') && - ( - check([0x00, 0x01, 0x00, 0x00], { offset: 4 }) || - checkString('OTTO', { offset: 4 }) - ) - ) { - return { - ext: 'woff2', - mime: 'font/woff2' - }; - } - - if (check([0xD4, 0xC3, 0xB2, 0xA1]) || check([0xA1, 0xB2, 0xC3, 0xD4])) { - return { - ext: 'pcap', - mime: 'application/vnd.tcpdump.pcap' - }; - } - - if (checkString('DSD ')) { - return { - ext: 'dsf', - mime: 'audio/x-dsf' - }; - } - - if (checkString('LZIP')) { - return { - ext: 'lz', - mime: 'application/x-lzip' - }; - } - - if (checkString('fLaC')) { - return { - ext: 'flac', - mime: 'audio/x-flac' - }; - } - - if (check([0x42, 0x50, 0x47, 0xFB])) { - return { - ext: 'bpg', - mime: 'image/bpg' - }; - } - - if (checkString('wvpk')) { - return { - ext: 'wv', - mime: 'audio/wavpack' - }; - } - - if (checkString('%PDF')) { - return { - ext: 'pdf', - mime: 'application/pdf' - }; - } - - if (check([0x00, 0x61, 0x73, 0x6D])) { - return { - ext: 'wasm', - mime: 'application/wasm' - }; - } - - if (check([0x49, 0x49, 0x2A, 0x0])) { - if (checkString('CR', { offset: 8 })) { - return { - ext: 'cr2', - mime: 'image/x-canon-cr2' - }; - } - - if (check([0x1C, 0x00, 0xFE, 0x00], { offset: 8 }) || check([0x1F, 0x00, 0x0B, 0x00], { offset: 8 })) { - return { - ext: 'nef', - mime: 'image/x-nikon-nef' - }; - } - - if ( - check([0x08, 0x00, 0x00, 0x00], { offset: 4 }) && - (check([0x2D, 0x00, 0xFE, 0x00], { offset: 8 }) || - check([0x27, 0x00, 0xFE, 0x00], { offset: 8 })) - ) { - return { - ext: 'dng', - mime: 'image/x-adobe-dng' - }; - } - - return { - ext: 'tif', - mime: 'image/tiff' - }; - } - - if (check([0x4D, 0x4D, 0x0, 0x2A])) { - return { - ext: 'tif', - mime: 'image/tiff' - }; - } - - if (checkString('MAC ')) { - return { - ext: 'ape', - mime: 'audio/ape' - }; - } - - if (check([0x1A, 0x45, 0xDF, 0xA3])) { - return { - ext: 'webm', - mime: 'video/webm' - }; - } - - if (check([0x52, 0x49, 0x46, 0x46])) { - if (check([0x41, 0x56, 0x49], { offset: 8 })) { - return { - ext: 'avi', - mime: 'video/vnd.avi' - }; - } - - if (check([0x57, 0x41, 0x56, 0x45], { offset: 8 })) { - return { - ext: 'wav', - mime: 'audio/vnd.wave' - }; - } - - if (check([0x51, 0x4C, 0x43, 0x4D], { offset: 8 })) { - return { - ext: 'qcp', - mime: 'audio/qcelp' - }; - } - } - - if (checkString('SQLi')) { - return { - ext: 'sqlite', - mime: 'application/x-sqlite3' - }; - } - - if (check([0x4E, 0x45, 0x53, 0x1A])) { - return { - ext: 'nes', - mime: 'application/x-nintendo-nes-rom' - }; - } - - if (checkString('Cr24')) { - return { - ext: 'crx', - mime: 'application/x-google-chrome-extension' - }; - } - - if ( - checkString('MSCF') || - checkString('ISc(') - ) { - return { - ext: 'cab', - mime: 'application/vnd.ms-cab-compressed' - }; - } - - if (check([0xED, 0xAB, 0xEE, 0xDB])) { - return { - ext: 'rpm', - mime: 'application/x-rpm' - }; - } - - if (check([0xC5, 0xD0, 0xD3, 0xC6])) { - return { - ext: 'eps', - mime: 'application/eps' - }; - } - - - if (check([0x4F, 0x54, 0x54, 0x4F, 0x00])) { - return { - ext: 'otf', - mime: 'font/otf' - }; - } - - if (checkString('#!AMR')) { - return { - ext: 'amr', - mime: 'audio/amr' - }; - } - - if (checkString('{\\rtf')) { - return { - ext: 'rtf', - mime: 'application/rtf' - }; - } - - if (check([0x46, 0x4C, 0x56, 0x01])) { - return { - ext: 'flv', - mime: 'video/x-flv' - }; - } - - if (checkString('IMPM')) { - return { - ext: 'it', - mime: 'audio/x-it' - }; - } - - if ( - checkString('-lh0-', { offset: 2 }) || - checkString('-lh1-', { offset: 2 }) || - checkString('-lh2-', { offset: 2 }) || - checkString('-lh3-', { offset: 2 }) || - checkString('-lh4-', { offset: 2 }) || - checkString('-lh5-', { offset: 2 }) || - checkString('-lh6-', { offset: 2 }) || - checkString('-lh7-', { offset: 2 }) || - checkString('-lzs-', { offset: 2 }) || - checkString('-lz4-', { offset: 2 }) || - checkString('-lz5-', { offset: 2 }) || - checkString('-lhd-', { offset: 2 }) - ) { - return { - ext: 'lzh', - mime: 'application/x-lzh-compressed' - }; - } - - - - if (check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) { - return { - ext: 'xz', - mime: 'application/x-xz' - }; - } - - if (checkString('')) { - return { - ext: 'ar', - mime: 'application/x-unix-archive' - }; - } - - if (check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) { - return { - ext: 'png', - mime: 'image/png' - }; - } - if (check([0x41, 0x52, 0x52, 0x4F, 0x57, 0x31, 0x00, 0x00])) { - return { - ext: 'arrow', - mime: 'application/x-apache-arrow' - }; - } - - if (check([0x67, 0x6C, 0x54, 0x46, 0x02, 0x00, 0x00, 0x00])) { - return { - ext: 'glb', - mime: 'model/gltf-binary' - }; - } - if ( - check([0x66, 0x72, 0x65, 0x65], { offset: 4 }) || - check([0x6D, 0x64, 0x61, 0x74], { offset: 4 }) || - check([0x6D, 0x6F, 0x6F, 0x76], { offset: 4 }) || - check([0x77, 0x69, 0x64, 0x65], { offset: 4 }) - ) { - return { - ext: 'mov', - mime: 'video/quicktime' - }; - } - - - if (check([0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00, 0x18])) { - return { - ext: 'orf', - mime: 'image/x-olympus-orf' - }; - } - if (check([0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8])) { - return { - ext: 'rw2', - mime: 'image/x-panasonic-rw2' - }; - } - - - if (check([0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A])) { - return { - ext: 'ktx', - mime: 'image/ktx' - }; - } - - if ((check([0x7E, 0x10, 0x04]) || check([0x7E, 0x18, 0x04])) && check([0x30, 0x4D, 0x49, 0x45], { offset: 4 })) { - return { - ext: 'mie', - mime: 'application/x-mie' - }; - } - - if (check([0x27, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], { offset: 2 })) { - return { - ext: 'shp', - mime: 'application/x-esri-shape' - }; - } - - if ( - check([0x0, 0x0, 0x1, 0xBA]) || - check([0x0, 0x0, 0x1, 0xB3]) - ) { - return { - ext: 'mpg', - mime: 'video/mpeg' - }; - } - - if (check([0x00, 0x01, 0x00, 0x00, 0x00])) { - return { - ext: 'ttf', - mime: 'font/ttf' - }; - } - - if (check([0x00, 0x00, 0x01, 0x00])) { - return { - ext: 'ico', - mime: 'image/x-icon' - }; - } - - if (check([0x00, 0x00, 0x02, 0x00])) { - return { - ext: 'cur', - mime: 'image/x-icon' - }; - } - - if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) { - return { - ext: 'cfb', - mime: 'application/x-cfb' - }; - } - - return undefined; -} - -function fromFile(file) { - return fromBuffer(require('fs').readFileSync(file)); -} - -module.exports = { - fromBuffer: fromBuffer, - fromFile: fromFile -} \ No newline at end of file diff --git a/lib/html-tags.json b/lib/html-tags.json deleted file mode 100644 index 5c58945..0000000 --- a/lib/html-tags.json +++ /dev/null @@ -1,119 +0,0 @@ -[ - "a", - "abbr", - "address", - "area", - "article", - "aside", - "audio", - "b", - "base", - "bdi", - "bdo", - "blockquote", - "body", - "br", - "button", - "canvas", - "caption", - "cite", - "code", - "col", - "colgroup", - "data", - "datalist", - "dd", - "del", - "details", - "dfn", - "dialog", - "div", - "dl", - "dt", - "em", - "embed", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hgroup", - "hr", - "html", - "i", - "iframe", - "img", - "input", - "ins", - "kbd", - "label", - "legend", - "li", - "link", - "main", - "map", - "mark", - "math", - "menu", - "menuitem", - "meta", - "meter", - "nav", - "noscript", - "object", - "ol", - "optgroup", - "option", - "output", - "p", - "param", - "picture", - "pre", - "progress", - "q", - "rb", - "rp", - "rt", - "rtc", - "ruby", - "s", - "samp", - "script", - "section", - "select", - "slot", - "small", - "source", - "span", - "strong", - "style", - "sub", - "summary", - "sup", - "svg", - "table", - "tbody", - "td", - "template", - "textarea", - "tfoot", - "th", - "thead", - "time", - "title", - "tr", - "track", - "u", - "ul", - "var", - "video", - "wbr" -] \ No newline at end of file diff --git a/lib/is-html.js b/lib/is-html.js deleted file mode 100644 index 03acbcb..0000000 --- a/lib/is-html.js +++ /dev/null @@ -1,5 +0,0 @@ -const tags = require('./html-tags.json'); - -const tester = new RegExp('(\\s*|(||]+>)+)|'+tags.map(t=>`<${t}[/\\s]*>`).join('|')); - -module.exports = str => tester.test(str.toString().toLowerCase()); \ No newline at end of file diff --git a/lib/qs.js b/lib/qs.js index 20b2d4e..26fe269 100644 --- a/lib/qs.js +++ b/lib/qs.js @@ -5,7 +5,7 @@ function processData(__data){ let d = {}, keys = __data.map(n=>n[0]), data = __data.map(n=>n[1]); for (let i = 0; i < keys.length; i++) { let current = d; - let keyParts = keys[i].split('[').join('.').split(']').join('').split('.'); + let keyParts = keys[i].split('[').join('.').split(']').join('').split('.'); for (let j = 0; j < keyParts.length; j++){ let k = keyParts[j]; @@ -32,4 +32,4 @@ function parse(data) { return processData(d); } -module.exports = parse; \ No newline at end of file +module.exports = parse; diff --git a/package-lock.json b/package-lock.json index f5b4cb7..0cdb6bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { "name": "serverfire", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 1 } diff --git a/package.json b/package.json index 9a9461f..a764497 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,17 @@ { "name": "serverfire", - "version": "1.0.2", + "version": "2.0.0", "description": "ServerFire is a new lightweight server library to help you create your website, light and powerful!", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "keywords": ["server", "web", "express-alternative", "dependency-free"], + "keywords": [ + "server", + "web", + "express-alternative", + "dependency-free" + ], "author": "AmazingMech2418", "license": "MIT" } diff --git a/src/defaults.js b/src/defaults.js new file mode 100644 index 0000000..61d25f2 --- /dev/null +++ b/src/defaults.js @@ -0,0 +1,9 @@ +const wrap = require("./utils/wrapper.js"); +const bp = require("./utils/middleware/body-parser.js"); + +function addDefaults(server) { + server.use(wrap); + server.use(bp); +} + +module.exports = addDefaults; diff --git a/src/server.js b/src/server.js new file mode 100644 index 0000000..da9d38a --- /dev/null +++ b/src/server.js @@ -0,0 +1,43 @@ +const http = require("http"); +const addDefaults = require("./defaults.js"); + +class Server { + constructor() { + this.utils = []; + this.server; + this.code = (req, res) => { + (async() => { + let data = {req: req, res: res}; + for(let util of this.utils) { + let utilRes; + if(util.constructor.name == "AsyncFunction") { + utilRes = await util(data); + } else { + utilRes = util(data); + } + data = Object.assign(Object.assign({}, data), utilRes); + } + })(); + } + + addDefaults(this); + } + + use(util) { + this.utils.push(util); + } + + create() { + this.server = http.createServer(this.code); + } + + getCode() { + return this.code; + } + + listen(port) { + this.server.listen(port); + } +} + +module.exports = Server; diff --git a/src/server/body-parser/middleware.js b/src/server/body-parser/middleware.js deleted file mode 100644 index f4b51a4..0000000 --- a/src/server/body-parser/middleware.js +++ /dev/null @@ -1,12 +0,0 @@ -const {generate, package} = require('../middleware-tools/gen.js'); -const parse = require('./parser.js'); - -module.exports = generate((req, res, head) => { - const _req = req; - _req.body = parse(_req.body); - return { - req: _req, - res: res, - head: head - } -}); \ No newline at end of file diff --git a/src/server/index.js b/src/server/index.js deleted file mode 100644 index 8ff1e7a..0000000 --- a/src/server/index.js +++ /dev/null @@ -1,38 +0,0 @@ -const http = require('http'); -const Response = require('./response/index.js'); - -class Server { - constructor() { - this.utils = []; - this.server; - this.code = (req, res) => { - let body = ''; - req.on('data', chunk => { - //console.log('chunk'); - body += chunk; - }); - req.on('end', () => { - const _req = Object.assign({}, req); - let data = { - req: Object.assign(_req, {body: body}), - res: res, - head: {} - }; - this.utils.forEach(util => { - data = util(data); - }); - }); - }; - } - use(fn) { - this.utils.push(fn); - } - create() { - this.server = http.createServer(this.code); - } - listen(port = 3000) { - this.server.listen(port); - } -} - -module.exports = Server; \ No newline at end of file diff --git a/src/server/middleware-tools/gen.js b/src/server/middleware-tools/gen.js deleted file mode 100644 index bf749c1..0000000 --- a/src/server/middleware-tools/gen.js +++ /dev/null @@ -1,14 +0,0 @@ -function genMiddleware(fn) { - return data => fn(data.req, data.res, data.head); -} - -const package = (req, res, head) => {return { - req: req, - res: res, - head: head -}}; - -module.exports = { - generate: genMiddleware, - package: package -}; \ No newline at end of file diff --git a/src/server/request/index.js b/src/server/request/index.js deleted file mode 100644 index 64e0034..0000000 --- a/src/server/request/index.js +++ /dev/null @@ -1,27 +0,0 @@ -class Request { - constructor(req) { - this.req = req; - } - get body() { - return this.req.body; - } - getHeader(header) { - return this.req.headers[header]; - } - get method() { - return this.req.method; - } - get url() { - return new URL(this.req.url, `http://${this.req.headers.host}`); - } - get status() { - return { - code: this.req.statusCode, - message: this.req.statusMessage - }; - } - get headers() { - return this.req.headers; - } -} -module.exports = Request; \ No newline at end of file diff --git a/src/server/response/index.js b/src/server/response/index.js deleted file mode 100644 index 749edbf..0000000 --- a/src/server/response/index.js +++ /dev/null @@ -1,61 +0,0 @@ -const fs = require('fs'); - -const mime = require('./mime/index.js'); - - -class Response { - constructor(res) { - this.res = res; - this.content = ''; - this.mime = 'text/plain'; - this.fileTemp = ''; - this.check = true; - } - send(data) { - this.content += String(data); - this.mime = {lookup: 'content'}; - } - sendFile(path) { - this.content = fs.readFileSync(path); - this.mime = {lookup: 'file'}; - this.fileTemp = path; - } - sendJSON(data) { - this.content = JSON.stringify(data); - this.mime = 'application/json'; - } - setHeader(header, value) { - this.res.setHeader(header, value); - if(header == 'Content-Type') { - this.check = false; - } - } - finish() { - if(this.check){ - if(typeof(this.mime) == 'object' && "lookup" in this.mime) { - if(this.mime.lookup == 'content') { - mime.string(this.content, (data) => { - this.res.setHeader('Content-Type', data); - this.res.write(this.content); - this.res.end(); - }) - } else { - mime.file(this.fileTemp, (data) => { - this.res.setHeader('Content-Type', data); - this.res.write(this.content); - this.res.end(); - }) - } - } else { - this.res.setHeader('Content-Type', this.mime); - this.res.write(this.content); - this.res.end(); - } - } else { - this.res.write(this.content); - this.res.end(); - } - } -} - -module.exports = Response; \ No newline at end of file diff --git a/src/server/response/mime/index.js b/src/server/response/mime/index.js deleted file mode 100644 index 089fa98..0000000 --- a/src/server/response/mime/index.js +++ /dev/null @@ -1,46 +0,0 @@ -const FileType = require('../../../../lib/file-type.js'); -const fs = require('fs'); -const isHTML = require('../../../../lib/is-html.js'); - - -const extensions = { - js: 'application/javascript', - css: 'text/css', - html: 'text/html', - xml: 'text/xml' -}; - -function mimeTypeFromFile(filePath, callback){ - (async () => { - //let data = await FileType.fromFile(filePath); - let data = FileType.fromFile(filePath); - if(data == undefined) { - const ext = filePath.split('.')[filePath.split('.').length - 1]; - if(ext in extensions) { - callback(extensions[ext]); - } else { - callback(isHTML(fs.readFileSync(filePath))?'text/html':'text/plain'); - } - } else { - callback(data.mime); - } - })(); -} - -function mimeTypeFromString(str, callback){ - const buffer = Buffer.from(str); - (async () => { - //let data = await FileType.fromBuffer(buffer); - let data = FileType.fromBuffer(buffer); - if(data == undefined) { - callback(isHTML(str)?'text/html':'text/plain'); - } else { - callback(data.mime); - } - })(); -} - -module.exports = { - file: mimeTypeFromFile, - string: mimeTypeFromString -}; \ No newline at end of file diff --git a/src/server/router/route.js b/src/server/router/route.js deleted file mode 100644 index 7d5e4ff..0000000 --- a/src/server/router/route.js +++ /dev/null @@ -1,75 +0,0 @@ -const Response = require('../response/index.js'); -const Request = require('../request/index.js'); -const {generate, package} = require('../middleware-tools/gen.js'); -const {compare, compareWithParams, compareBases} = require('./url-tools/compare.js'); - -function generateRoute(router) { - const route = generate((req, res, head) => { - const response = new Response(res) - const request = new Request(req) - const paths = router.paths; - const statics = router.statics; - let asynchronous = false; - let found = false; - paths.forEach(path => { - if(request.method == path.method) { - if(compare(request.req.url, path.path)) { - found = true; - if(path.asynchronous) { - asynchronous = true; - } - if(path.fn(request, response) == "ERR") - found = false; - } else if(compareWithParams(path.path, request.req.url, request)) { - found = true; - if(path.asynchronous) { - asynchronous = true; - } - if(path.fn(request, response) == "ERR") - found = false; - }; - } - }); - if(!found) { - statics.forEach(path => { - //path.path - if(compareBases(path.path, request.req.url)) { - let part = decodeURIComponent(require('path').normalize(request.req.url).replace(path.path, '')); - if(path.file[path.file.length - 1] != '/' && part[0] != '/') - part = '/' + part; - try { - if(require('fs').lstatSync(path.file + part).isFile()) { - response.sendFile(path.file + part); - found = true; - } else if(require('fs').existsSync(path.file + part + 'index.html') && require('fs').lstatSync(path.file + part + 'index.html').isFile()) { - response.sendFile(path.file + part + 'index.html'); - found = true; - } else if(require('fs').existsSync(path.file + part + '/index.html') && require('fs').lstatSync(path.file + part + '/index.html').isFile()) { - response.send(``); - found = true; - } else { - response.send("Cannot find file " + path.file + part); - found = true; - } - } catch(e) { - // Nothing... - } - } - }); - } - if(!found) { - response.send(`Cannot ${request.method} ${request.req.url}`); - } - if(!asynchronous) { - response.finish(); - } - return { - req: req, - res: res, - head: head - }; - }); - return route; -} - -module.exports = generateRoute; diff --git a/src/server/body-parser/parser.js b/src/utils/body-parser.js similarity index 89% rename from src/server/body-parser/parser.js rename to src/utils/body-parser.js index fdf6c98..b5c5215 100644 --- a/src/server/body-parser/parser.js +++ b/src/utils/body-parser.js @@ -1,6 +1,6 @@ let qs = {};//require('qs'); //let qs = require('qs'); -qs.parse = require('../../../lib/qs.js');//require('qs'); +qs.parse = require('../../lib/qs.js');//require('qs'); function parse(data,log=false) { try { @@ -41,4 +41,4 @@ function parse(data,log=false) { return {}; } -module.exports = parse; \ No newline at end of file +module.exports = parse; diff --git a/src/utils/middleware/body-parser.js b/src/utils/middleware/body-parser.js new file mode 100644 index 0000000..72d3474 --- /dev/null +++ b/src/utils/middleware/body-parser.js @@ -0,0 +1,11 @@ +const {generate, package} = require('./middleware.js'); +const parse = require('../body-parser.js'); + +module.exports = generate((req, res) => { + const _req = req; + _req.body = parse(_req.body); + return { + req: _req, + res: res + } +}); diff --git a/src/utils/middleware/middleware.js b/src/utils/middleware/middleware.js new file mode 100644 index 0000000..0eea353 --- /dev/null +++ b/src/utils/middleware/middleware.js @@ -0,0 +1,18 @@ +function genMiddleware(fn) { + return data => fn(data.req, data.res); +} + +function genMiddlewareAsync(fn) { + return async data => await fn(data.req, data.res); +} + +const package = (req, res, head) => {return { + req: req, + res: res +}}; + +module.exports = { + generate: genMiddleware, + genAsync: genMiddlewareAsync, + package: package +}; diff --git a/src/utils/router/route.js b/src/utils/router/route.js new file mode 100644 index 0000000..b13da21 --- /dev/null +++ b/src/utils/router/route.js @@ -0,0 +1,84 @@ +const fs = require("fs"); + +const Response = require('../wrappers/res.js'); +const Request = require('../wrappers/req.js'); +const {genAsync, package} = require('../middleware/middleware.js'); +const {compare, compareWithParams, compareBases} = require('./url-tools/compare.js'); + +function generateRoute(router) { + const route = genAsync(async (req, res) => { + const paths = router.paths; + const statics = router.statics; + + let found = false; + for(const path of paths) { + if(req.method == path.method) { + if(compare(req.raw.url, path.path)) { + found = true; + + try { + if(path.fn.constructor.name == "AsyncFunction") { + await path.fn(req, res); + } else { + path.fn(req, res); + } + } catch(e) { + found = false; + } + } else if(compareWithParams(path.path, req.raw.url, req)) { + found = true; + + try { + if(path.fn.constructor.name == "AsyncFunction") { + await path.fn(req, res); + } else { + path.fn(req, res); + } + } catch(e) { + found = false; + } + } + } + } + if(!found) { + statics.forEach(path => { + //path.path + if(compareBases(path.path, req.raw.url)) { + let part = decodeURIComponent(require('path').normalize(req.raw.url).replace(path.path, '')); + if(path.file[path.file.length - 1] != '/' && part[0] != '/') + part = '/' + part; + try { + if(fs.lstatSync(path.file + part).isFile()) { + res.sendFile(path.file + part); + found = true; + } else if(fs.existsSync(path.file + part + 'index.html') && fs.lstatSync(path.file + part + 'index.html').isFile()) { + res.sendFile(path.file + part + 'index.html'); + found = true; + } else if(fs.existsSync(path.file + part + '/index.html') && fs.lstatSync(path.file + part + '/index.html').isFile()) { + res.send(``); + found = true; + } else { + res.send("Cannot find file " + path.file + part); + found = true; + } + } catch(e) { + // Nothing... + } + } + }); + } + if(!found) { + res.send(`Cannot ${req.method} ${req.raw.url}`); + } + + + res.finish(); + return { + req: req, + res: res + }; + }); + return route; +} + +module.exports = generateRoute; diff --git a/src/server/router/router.js b/src/utils/router/router.js similarity index 59% rename from src/server/router/router.js rename to src/utils/router/router.js index 46d6df7..3a1fc43 100644 --- a/src/server/router/router.js +++ b/src/utils/router/router.js @@ -9,19 +9,18 @@ class Router { this.paths.push({ method: method, path: path, - fn: fn, - asynchronous: asynchronous + fn: fn }); } - get(path, fn, asynchronous=false) { - this._addPath('GET', path, fn, asynchronous); + get(path, fn) { + this._addPath('GET', path, fn); } - post(path, fn, asynchronous=false) { - this._addPath('POST', path, fn, asynchronous); + post(path, fn) { + this._addPath('POST', path, fn); } - all(path, fn, asynchronous=false) { - this.get(path, fn, asynchronous); - this.post(path, fn, asynchronous); + all(path, fn) { + this.get(path, fn); + this.post(path, fn); } static(path, file) { if(normalize(path)[0] != '/' || normalize(file)[0] != '/') { @@ -36,4 +35,4 @@ class Router { } } -module.exports = Router; \ No newline at end of file +module.exports = Router; diff --git a/src/server/router/url-tools/compare.js b/src/utils/router/url-tools/compare.js similarity index 100% rename from src/server/router/url-tools/compare.js rename to src/utils/router/url-tools/compare.js diff --git a/src/utils/wrapper.js b/src/utils/wrapper.js new file mode 100644 index 0000000..b3ce0a4 --- /dev/null +++ b/src/utils/wrapper.js @@ -0,0 +1,8 @@ +const Request = require("./wrappers/req.js"); +const Response = require("./wrappers/res.js"); + +function wrap(data) { + return {res: new Response(data.res), req: new Request(data.req)}; +} + +module.exports = wrap; diff --git a/src/utils/wrappers/req.js b/src/utils/wrappers/req.js new file mode 100644 index 0000000..db76463 --- /dev/null +++ b/src/utils/wrappers/req.js @@ -0,0 +1,35 @@ +class Request { + constructor(req) { + this.raw = req; + } + + getHeader(header) { + return this.raw.headers[header]; + } + + getHeaders() { + return this.raw.headers; + } + + get method() { + return this.raw.method; + } + + get url() { + return new URL(this.raw.url, `http://${this.raw.headers.host}`); + } + + get status() { + return { + code: this.raw.statusCode, + message: this.raw.statusMessage + }; + } + + // Backwards Compatibility + get headers() { + return this.raw.headers; + } +} + +module.exports = Request; diff --git a/src/utils/wrappers/res.js b/src/utils/wrappers/res.js new file mode 100644 index 0000000..afe6c02 --- /dev/null +++ b/src/utils/wrappers/res.js @@ -0,0 +1,44 @@ +const fs = require("fs"); + +class Response { + constructor(res) { + this.raw = res; + this.content = ""; + } + + send(data) { + this.content += data; + } + + sendFile(path) { + this.content = fs.readFileSync(path); + } + + sendJSON(data) { + this.content = JSON.stringify(data); + this.raw.setHeader("Content-Type", "application/json"); + } + + setHeader(header, value) { + this.raw.setHeader(header, value); + } + + setMime(type) { + this.raw.setHeader("Content-Type", type); + } + + getHeaders() { + return this.raw.getHeaders(); + } + + setStatusCode(code) { + this.raw.writeHead(code); + } + + finish() { + this.raw.write(this.content); + this.raw.end(); + } +} + +module.exports = Response; diff --git a/tools/cors.js b/tools/cors.js index a52dcd4..121a443 100644 --- a/tools/cors.js +++ b/tools/cors.js @@ -1,11 +1,11 @@ -const {generate} = require('../src/server/middleware-tools/gen.js'); +const {generate} = require("../src/utils/middleware/middleware.js"); -module.exports = generate((req, _res, head) => { +module.exports = generate((req, _res) => { _res.setHeader("Access-Control-Allow-Origin", "*"); _res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); + return { req: req, - res: _res, - head: head - } -}); \ No newline at end of file + res: _res + }; +});