Comparing version 0.2.1 to 0.3.0
29
index.js
// vanyle backend library | ||
"use strict"; | ||
@@ -7,3 +8,4 @@ const docgen = require("./lib/docgen.js"); | ||
const middleware = require("./middleware.js"); | ||
const fs = require('fs'); | ||
const fs = require("fs"); | ||
const http = require("http"); | ||
@@ -55,2 +57,5 @@ // TODO: put the three following functions in a separate file | ||
self.files = {}; | ||
self.folders = {}; | ||
self.appname = config.appname; | ||
@@ -66,3 +71,13 @@ self.url = config.url || "q"; | ||
if(self.sql === undefined){ | ||
// use sqlite3 as default db. | ||
console.error(`config.sql is not defined. | ||
Tou need to provide sql functions to use the SQL related features of VBel2. | ||
To disable this warning, add this: | ||
sql:{ | ||
_run: (statement,...args) => {}, | ||
_get_all: (statement,...args) => {} | ||
} | ||
to your config or at least: | ||
sql:null`); | ||
} | ||
@@ -311,6 +326,7 @@ | ||
// Used to serve static files. Option for compilation purposes (templating, caching, etc ...) | ||
// Options is currently not implemented. | ||
// Note that if filename refers to a directory, this will provide the entire directory. | ||
file(href,filename,options){ | ||
this.compiled = false; | ||
} | ||
this.files[href] = {filename,options}; | ||
} | ||
@@ -1085,5 +1101,8 @@ // Used to call endpoints without any HTTP request. | ||
} | ||
listen(){ | ||
let server = http.createServer(this); | ||
return server.listen.apply(server, arguments); | ||
} | ||
} | ||
module.exports = VBel; |
@@ -0,4 +1,6 @@ | ||
"use strict"; | ||
const url = require('url'); | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
function sendError(res,description,code,fatal){ | ||
@@ -33,3 +35,90 @@ if(typeof description !== "string"){ | ||
} | ||
if(query_path == "/doc" && vbel.doc){ // provide debug documentation | ||
for(let paths in vbel.files){ | ||
if(query_path.startsWith(paths)){ | ||
let striped_query = query_path.substring(paths.length); | ||
let f_path = vbel.files[paths].filename; | ||
let file_path = f_path + '/' + path.normalize(striped_query); | ||
// remove ../.. from file_path. | ||
while(file_path.endsWith('/')){ | ||
file_path = file_path.substring(0,file_path.length-1); | ||
} | ||
file_path = path.normalize(file_path); | ||
if(!fs.existsSync(file_path)){ | ||
continue; | ||
} | ||
let file_info = null; | ||
try{ | ||
file_info = fs.lstatSync(file_path); | ||
}catch(err){ | ||
continue; | ||
} | ||
if(file_info.isFile()){ | ||
let range = req.headers.range; | ||
let content_type = "application/octet-stream"; | ||
// we provide content type for common file types. | ||
if(file_path.endsWith('.css')){ | ||
content_type = "text/css"; | ||
}else if(file_path.endsWith('.html')){ | ||
content_type = "text/html"; | ||
}else if(file_path.endsWith('.js')){ | ||
content_type = "application/javascript"; | ||
}else if(file_path.endsWith('.png')){ | ||
content_type = "image/png"; | ||
}else if(file_path.endsWith('.jpg')){ | ||
content_type = "image/jpg"; | ||
}else if(file_path.endsWith('.txt')){ | ||
content_type = "text/plain"; | ||
} | ||
if(!range){ | ||
res.writeHead(200, { | ||
"Content-Type": content_type | ||
}); | ||
// stream file output to res. | ||
let stream = fs.createReadStream(file_path); | ||
stream.on('data',(chunk) =>{ | ||
res.write(chunk); | ||
}); | ||
stream.on('end',() => { | ||
res.end(); | ||
}); | ||
return; | ||
}else{ | ||
// needed to serve large files. | ||
let stats = fs.statSync(fpath); | ||
let positions = range.replace(/bytes=/, "").split("-"); | ||
let start = parseInt(positions[0], 10); | ||
let total = stats.size; | ||
let end = positions[1] ? parseInt(positions[1], 10) : total - 1; | ||
let chunksize = (end - start) + 1; | ||
res.writeHead(206, { | ||
"Content-Range": "bytes " + start + "-" + end + "/" + total, | ||
"Accept-Ranges": "bytes", | ||
"Content-Length": chunksize, | ||
"Content-Type": content_type | ||
}); | ||
let stream = fs.createReadStream(fpath, { start: start, end: end }) | ||
.on("open", function() { | ||
stream.pipe(res); | ||
}).on("error", function(err) { | ||
res.end(err); | ||
}); | ||
} | ||
}else{ | ||
// not a file, probably a directory. | ||
// we don't provide a directory view. | ||
continue; | ||
} | ||
} | ||
} | ||
if(query_path === "/doc" && vbel.doc){ // provide debug documentation | ||
res.write(vbel.debug_template); | ||
@@ -36,0 +125,0 @@ res.end(); |
{ | ||
"name": "vbel2", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "An opiniated back-end framework", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -18,3 +18,2 @@ # VBel2 | ||
const VBel = require('vbel2'); | ||
const http = require('http'); | ||
@@ -24,3 +23,2 @@ let vbel = new VBel(); | ||
// Define endpoints | ||
vbel.endpoint("hello", {name:{"type":"string"}}, (obj,req,res) => { | ||
@@ -34,13 +32,21 @@ vbel.sendSuccess(`Hello ${obj.name}`); | ||
vbel.compile(); // call compile before use | ||
vbel.listen(8080,() => { | ||
console.log("http://localhost:8080") | ||
}); | ||
``` | ||
let server = http.createServer({},vbel); | ||
You can also use VBel just to serve static files or folders: | ||
server.listen(8080,() => { | ||
```js | ||
const VBel = require('vbel2'); | ||
let vbel = new VBel(); | ||
vbel.file("/","file.html"); // serve a static file | ||
vbel.file("/static","static/"); // serve all the files inside this directory | ||
vbel.listen(8080,() => { | ||
console.log("http://localhost:8080") | ||
}); | ||
``` | ||
## Overview | ||
@@ -47,0 +53,0 @@ |
11
test.js
@@ -69,3 +69,4 @@ /** | ||
let config = { | ||
doc:true | ||
doc:true, | ||
sql:null | ||
}; | ||
@@ -86,3 +87,4 @@ | ||
let config = { | ||
client_script: "/the/endpoint_script.js" // "/client.js" by default | ||
client_script:"/the/endpoint_script.js", // "/client.js" by default | ||
sql:null | ||
}; | ||
@@ -106,3 +108,4 @@ | ||
let config = { | ||
url: "query" // "q" by default | ||
url: "query", // "q" by default | ||
sql:null | ||
} | ||
@@ -139,3 +142,3 @@ let vbel = new VBel(config); | ||
test('perform proper type checking of endpoint arguments', (done) => { | ||
let vbel = new VBel({}); | ||
let vbel = new VBel({sql:null}); | ||
@@ -142,0 +145,0 @@ let notANumber = "Hello"; |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
80147
14
1720
282
5
8