Compare commits

..

No commits in common. "c4f59fbb0150af710e5714d2d4dd2454d70869d7" and "2e1dadbdeaa33b63aa2a0ee947eaf32d848315cd" have entirely different histories.

13 changed files with 462 additions and 4243 deletions

View file

@ -1,10 +1,9 @@
import { summary, run, bench } from 'mitata'; import { summary, run, bench } from 'mitata';
import { createRouter, insertItem } from '@mapl/router' import { createRouter, insertItem } from '@mapl/router'
import { compileRouter } from './mapl_compiler.mjs' import { compileRouter } from './mapl_compiler.mjs'
import assert from 'assert'
import { compilePaths } from "./router_v2.mjs" import { compilePaths } from "./router_v2.mjs"
import { compilePaths as mainCompiler } from "../router_v2.mjs" import { compilePaths as mainCompiler, compilePathsClosure } from "../router_v2.mjs"
import { FlaskaRouter as FlaskaRouterBuffer } from "../flaska_buffer.mjs"
import { FlaskaRouter as FlaskaRouterFast } from "../flaska_fast.mjs"
import * as consts from './const.js' import * as consts from './const.js'
function printCurrentStatus(fn) { function printCurrentStatus(fn) {
@ -37,21 +36,13 @@ function printStatusHelperText() {
bench('noop', () => { }); bench('noop', () => { });
bench('noop2', () => { }); bench('noop2', () => { });
let paths = consts.allRoutes.map(x => ({ path: x })) let paths = consts.allManyRoutes.map(x => ({ path: x }))
let tests = paths.map(p => ([p.path.replace(/:[^/]+/g, '_'), p])) let tests = paths.map(p => ([p.path.replace(/:[^/]+/g, '_'), p]))
let testStrings = tests.map(x => x[0]) let testStrings = tests.map(x => x[0])
let testStringsMapl = testStrings.map(x => x.slice(1)) let testStringsMapl = testStrings.map(x => x.slice(1))
let func = [[testStrings, mainCompiler(paths)]]
let flaskaRouterBuffer = new FlaskaRouterBuffer() let func = [[testStrings, ...mainCompiler(paths)]]
flaskaRouterBuffer.paths = paths.slice() func.push([testStrings, ...compilePathsClosure(paths)])
flaskaRouterBuffer.compile()
func.push([testStrings, flaskaRouterBuffer.match])
let flaskaRouterFast = new FlaskaRouterFast()
flaskaRouterFast.paths = paths.slice()
flaskaRouterFast.compile()
func.push([testStrings, flaskaRouterFast.match])
let maplPaths = paths.map(x => x.path.replace(/::[^\/]+/g, '**').replace(/:[^\/]+/g, '*')) let maplPaths = paths.map(x => x.path.replace(/::[^\/]+/g, '**').replace(/:[^\/]+/g, '*'))
const maplRouter = createRouter(); const maplRouter = createRouter();
@ -60,15 +51,15 @@ for (let route of maplPaths) {
} }
let maplMatcher = compileRouter(maplRouter) let maplMatcher = compileRouter(maplRouter)
func.push([testStringsMapl, maplMatcher]) func.push([testStringsMapl, maplMatcher, maplMatcher])
for (let [tests, fun] of func) { for (let [tests, _, fun] of func) {
console.log(`--- warming up ${fun.name || 'mapl'} ---`) console.log(`--- warming up ${fun.name || 'mapl'} ---`)
for (var i = 0; i < 100000; i++) { for (var i = 0; i < 10000; i++) {
tests.forEach(fun) tests.forEach(fun)
} }
} }
for (let [tests, fun] of func) { for (let [tests, _, fun] of func) {
console.log(`--- Sanity checking ${fun.name || 'mapl'} ---`) console.log(`--- Sanity checking ${fun.name || 'mapl'} ---`)
for (let a of tests) { for (let a of tests) {
// console.log(a, fun(a)) // console.log(a, fun(a))
@ -82,9 +73,9 @@ for (let [_, org] of func) {
printStatusHelperText() printStatusHelperText()
summary(() => { summary(() => {
func.forEach(function([tests, fun]) { func.forEach(function([tests, _, fun]) {
// console.log(tests, fun, tests.map(fun)) // console.log(tests, fun, tests.map(fun))
bench(fun.name || 'mapl', function() { bench((fun.name || 'bound mapl').slice(6), function() {
return tests.map(fun) return tests.map(fun)
}) })
}) })

View file

@ -1,117 +0,0 @@
import { summary, run, bench } from 'mitata';
// Warmup (de-optimize `bench()` calls)
bench('noop', () => { });
bench('noop2', () => { });
function padStart(length) {
return ''.padStart(length * 2)
}
const data = [
'/',
'/api/articles',
'/api/articles/:id/file',
'/api/articles/:id',
'/api/articles/public',
'/api/articles/public/:id',
'/api/categories',
'/api/categories/:categoryId/products',
'/api/categories/:categoryId/properties',
'/api/categories/:categoryId/values/:props',
'/api/categories/:categoryId',
//'/api/categories/:categoryId/products/:productId',
'/api/categories/:categoryId/products/:productId',
'/api/customers',
'/api/customers/:id',
'/api/customers/kennitala/:kennitala',
'/api/customers/public/kennitala/:kennitala',
'/api/customers/search/:search',
'/api/file',
'/api/file/:id',
'/api/media',
'/api/media/:id',
'/api/orderitem',
'/api/orderitem/:id',
'/api/orders',
'/api/orders/:orderId',
'/api/orders/:orderId/sell',
'/api/pages',
'/api/pages/:pageId',
'/api/pages/:pageId/articles',
'/api/pages/:pageId/articles/public',
'/api/products',
'/api/products/:id',
'/api/products/:id/movement',
'/api/products/:id/sub_products/:productId',
//'/api/products/:id/sub_products/:productId',
'/api/products/code/:code',
'/api/products/property/:propertyId',
'/api/properties',
'/api/properties/:id',
'/api/sales',
'/api/sales/:id',
'/api/stockitem',
'/api/stockitem/:id',
'/api/stocks',
'/api/stocks/:id',
'/api/stocks/:id/commit',
'/api/test',
'/api/test/auth',
'/api/test/error',
'/api/workentries',
'/api/workentries/:id',
'/api/works',
'/api/works/:id',
'/api/works/:id/lock',
'/api/works/public',
'/api/staff',
'/api/staff/:id',
'/::rest',
]
function arrIncludes(data) {
let out = new Array()
for (let item of data) {
if (out.includes(item)) { break }
out.push(item)
}
return out
}
function setAdd(data) {
let s = new Set()
for (let item of data) {
let size = s.size
if (s.add(item).size === size) { break }
}
return s
}
let func = [arrIncludes, setAdd];
for (let fun of func) {
console.log(`--- warming up ${fun.name || 'mapl'} ---`)
for (var i = 0; i < 100; i++) {
fun(data)
}
}
await new Promise(res => setTimeout(res, 3000))
summary(() => {
for (let i = 20; i >= 0; i--) {
const dataSet = data.slice(0, data.length - i)
func.forEach(function(fun) {
bench(`${dataSet.length} items: ${fun.name}`, function() {
return fun(dataSet)
})
})
}
// console.log(tests, fun, tests.map(fun))
/*bench(fun.name, function() {
return fun(data)
})*/
})
run();

View file

@ -37,6 +37,16 @@ export const MimeTypeDb = getDb()
* Router * Router
*/ */
class Branch {
constructor() {
this.children = new Map()
this.paramName = null
this.fullparamName = null
this.handler = null
this.middlewares = []
}
}
export const ErrorCodes = { export const ErrorCodes = {
ERR_CONNECTION_ABORTED: 'ERR_CON_ABORTED' ERR_CONNECTION_ABORTED: 'ERR_CON_ABORTED'
} }
@ -393,312 +403,190 @@ export class FileResponse {
} }
} }
/*
* --- Router ---
*/
class RouterError extends Error {
constructor(route1, route2, ...params) {
// Pass remaining arguments (including vendor specific ones) to parent constructor
super(...params);
// Maintains proper stack trace for where our error was thrown (only available on V8)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, RouterError);
}
this.name = "RouterError";
this.routeA = route1
this.routeB = route2
}
}
function Child(split, x, i) {
this.path = null
this.isParams = split[x].isParams ? split[x].word : null
this.isFullParams = split[x].isFullParams ? split[x].word : null
this.paramVarName = split[x].paramVarName ?? null
this.char = !this.isParams && !this.isFullParams ? split[x].word[i] || '/' : null
this.count = 0
this.children = []
}
const regParamPrefix = /^::?/
const regCleanNonAschii = /(?![a-zA-Z_])./g
const regCleanRest = /_+/g
const regStarDoubleParam = /::[^:/]+/g
const regStarSingleParam = /:[^:/]+/g
const SlashCode = '/'.charCodeAt(0)
const spaces = ' '
export class FlaskaRouter { export class FlaskaRouter {
constructor() { constructor() {
this.paths = [] this.root = new Branch()
this.registeredPaths = new Set()
} }
addRoute(path, middlewares, orgHandler) { addRoute(route, orgMiddlewares, orgHandler) {
if (path[0] !== '/') if (route[0] !== '/')
throw new RouterError(null, null, `addRoute("${path}") path must start with forward slash`) throw new Error(`route "${route}" must start with forward slash`)
let cleaned = path let middlewares = orgMiddlewares
if (cleaned.indexOf('/:') >= 0) { let handler = orgHandler
cleaned = cleaned.replace(regStarDoubleParam, '**').replace(regStarSingleParam, '*') if (!orgHandler) {
if (cleaned.indexOf(':') > 0) { handler = orgMiddlewares
throw new RouterError(null, null, `addRoute("${path}") path has missing name or word between two forward slashes`) middlewares = []
}
if (middlewares && typeof(middlewares) === 'function') {
middlewares = [middlewares]
}
assertIsHandler(handler, 'addRoute()')
let start = 1
let end = 1
let name = ''
let param = ''
let isParam = false
let isFullParam = false
let branch = this.root
if (route.indexOf(':') < 0 && false) {
let name = route
if (name.length > 1 && name[name.length - 1] === '/') {
name = name.slice(0, -1)
} }
if (cleaned.indexOf('**/') > 0) { let child = new Branch()
throw new RouterError(null, null, `addRoute("${path}") cannot add anything after a full param route`) branch.children.set(name, child)
} child.handler = handler
} child.middlewares = middlewares
if (cleaned.indexOf('//') >= 0) {
throw new RouterError(null, null, `addRoute("${path}") path has missing name or word between two forward slashes`)
} }
let size = this.registeredPaths.size for (let i = 1; i <= route.length; i++) {
if (this.registeredPaths.add(cleaned).size === size) { if ((i === route.length || route[i] === '/') && end > start) {
throw new RouterError(null, null, `addRoute("${path}") found an existing route with same path of ${cleaned}`) if (branch.fullparamName) {
} throw new Error(`route "${route}" conflicts with a sub-branch that has a full param child`)
}
let handlers = [] let child
if (Array.isArray(middlewares)) { name = route.substring(start, end)
handlers.push(...middlewares) if (isFullParam) {
if (typeof(orgHandler) !== 'function') { param = name
throw new RouterError(orgHandler, null, `addRoute("${path}") was called with a handler that was not a function`) name = __fullParamMapName
} } else if (isParam) {
} else { param = name
handlers.push(middlewares) name = __paramMapName
} }
if (orgHandler) { if (branch.children.has(name)) {
handlers.push(orgHandler) child = branch.children.get(name)
} }
for (let handler of handlers) { else if (isParam && !isFullParam && branch.children.has(__fullParamMapName)) {
if (typeof(handler) !== 'function') { throw new Error(`route "${route}" conflicts with a sub-branch that has a full param child`)
throw new RouterError(handler, null, `addRoute("${path}") was called with a handler that was not a function`) }
} else if (isFullParam && branch.children.has(__paramMapName)) {
} throw new Error(`route "${route}" conflicts with a sub-branch that has a partial param child`)
}
this.paths.push({ else {
path, child = new Branch()
handlers branch.children.set(name, child)
}) }
} branch = child
end = i
__buildChild(x, i, splitPaths) { start = i
let splitPath = splitPaths[0] if (isParam) {
let letter = new Child(splitPath.split, x, i) if (branch.paramName && branch.paramName !== param) {
throw new Error(`route "${route}" conflicts with pre-existing param name of ${branch.paramName} instead of ${param}`)
let consume = []
if (splitPath.split.length === x + 1
&& (splitPath.split[x].isParams
|| splitPath.split[x].isFullParams
|| splitPath.split[x].word.length === i + 1)) {
letter.path = splitPath.entry
letter.count += 1
} else {
consume = [splitPath]
}
for (let y = 1; y < splitPaths.length; y++) {
let checkPath = splitPaths[y]
if (!checkPath.split[x]
|| checkPath.split[x].isParams !== splitPath.split[x].isParams
|| checkPath.split[x].isFullParams !== splitPath.split[x].isFullParams
|| !checkPath.split[x].isParams
&& !checkPath.split[x].isFullParams
&& (checkPath.split[x].word[i] || '/') !== letter.char) break
consume.push(checkPath)
}
letter.count += consume.length
if (splitPath.split[x].word.length === i || splitPath.split[x].isParams || splitPath.split[x].isFullParams) {
x++
i = -1
}
while (consume.length) {
letter.children.push(this.__buildChild(x, i + 1, consume))
consume.splice(0, letter.children[letter.children.length - 1].count)
}
return letter
}
__buildTree(splitPaths) {
let builder = []
while (splitPaths.length) {
builder.push(this.__buildChild(0, 0, splitPaths))
splitPaths.splice(0, builder[builder.length - 1].count)
}
return builder
}
__splitAndSortPaths(paths, separateStatic = true) {
let staticPaths = new Map()
let paramsPaths = []
let collator = new Intl.Collator('en', { sensitivity: 'accent' });
paths.forEach(function(entry) {
if (entry.path[0] !== '/') throw new RouterError(entry, null, 'Specified route was missing forward slash at start')
// Collect static paths separately
if (entry.path.indexOf('/:') < 0 && separateStatic) {
return staticPaths.set(entry.path, {
path: entry,
params: {}
})
}
// Collect params path separately
paramsPaths.push({
split: entry.path.slice(1).split(/\//g).map(function(word) {
let actualWord = word.replace(regParamPrefix, '')
return {
word: actualWord,
isParams: word[0] === ':' && word[1] !== ':',
isFullParams: word[0] === ':' && word[1] === ':',
paramVarName: word[0] === ':'
? actualWord.replace(regCleanNonAschii, '_').replace(regCleanRest, '_')
: null
} }
}), if (isFullParam) {
entry, branch.fullparamName = param
}) } else {
}) branch.paramName = param
paramsPaths.sort(function(aGroup, bGroup) { }
let length = Math.max(aGroup.split.length, bGroup.split.length) isParam = false
for (let x = 0; x < length; x++) { }
let a = aGroup.split[x] } else if (route[i] === '/' && end === start) {
let b = bGroup.split[x] throw new Error(`route "${route}" has missing path name inbetween slashes`)
if (!a) return -1
if (!b) return 1
// Full params go last
if (a.isFullParams && b.isFullParams) throw new RouterError(aGroup.entry, bGroup.entry, 'Two full path routes found on same level')
if (a.isFullParams) return 1
if (b.isFullParams) return -1
// Params go second last
if (a.isParams && !b.isParams) return 1
if (!a.isParams && b.isParams) return -1
// otherwise sort alphabetically if not identical
if (a.word !== b.word) return collator.compare(a.word, b.word)
} }
throw new RouterError(aGroup, bGroup, 'Two identical paths were found') if (i === route.length) {
}) branch.handler = handler
branch.middlewares = middlewares
return { continue
staticPaths, }
paramsPaths, if (route[i] === ':') {
} if (isParam) {
} isFullParam = true
}
isParam = true
__getIndex(offset, additions, params) { end = start = i + 1
return (offset + additions) }
+ (params.length else if (route[i] === '/') {
? ' + ' + params.map(a => `offset${a[1]}`).join(' + ') end = start = i + 1
: '') }
} else {
end++
__treeIntoCompiledCodeReturnPath(indentString, paths, branch, params) {
let pathIndex = paths.indexOf(branch.path)
if (pathIndex < 0) {
throw new RouterError(branch.path, null, 'InternalError: Specified path was not found in paths')
}
let output = '\n' + indentString + `return {`
output += '\n' + indentString + ` path: paths[${pathIndex}],`
if (params.length) {
output += '\n' + indentString + ` params: {`
for (let param of params) {
output += '\n' + indentString + ` ${param[0]}: s${param[1]},`
} }
output += '\n' + indentString + ` },`
} else {
output += '\n' + indentString + ` params: {},`
} }
output += '\n' + indentString + `}`
return output
} }
__treeIntoCompiledCodeBranch(paths, branches, indent = 0, params = []) { match(orgUrl) {
let output = '' let url = orgUrl
let indentation = spaces.slice(0, (indent - params.length) * 2) if (url.length > 1 && url[url.length - 1] === '/') {
let addEndBracket = true url = url.slice(0, -1)
}
for (let i = 0; i < branches.length; i++) { let branch = this.root
let branch = branches[i] let start = 1
if (i > 0) { let end = 1
if (!branch.isParams && !branch.isFullParams) { let output
output += ' else ' let name
let char
let params = {}
if (output = branch.children.get(url)) {
return {
handler: output.handler,
middlewares: output.middlewares,
params: params,
}
}
for (let i = 1; i <= url.length; i++) {
char = url[i]
if ((i === url.length || char === '/') && end > start) {
name = url.slice(start, end)
if (output = branch.children.get(name)) {
branch = output
}
else if (output = branch.children.get(__paramMapName)) {
branch = output
params[branch.paramName] = name
}
else if (output = branch.children.get(__fullParamMapName)) {
params[output.fullparamName] = url.slice(start)
return {
handler: output.handler,
middlewares: output.middlewares,
params: params,
}
} else { } else {
// output += '} //' if (output = this.root.children.get(__fullParamMapName)) {
output += '\n' + indentation params = {
[output.fullparamName]: url.slice(1)
}
return {
handler: output.handler,
middlewares: output.middlewares,
params: params,
}
}
return null
}
i++
end = start = i
char = url[i]
}
// Check branch.handler. This can happen if route /::path is added
// and request is '/' it will attempt to match root which will fail
if (i >= url.length && branch.handler) {
return {
handler: branch.handler,
middlewares: branch.middlewares,
params: params,
} }
} }
if (char === '/') {
if (!branch.isParams && !branch.isFullParams) { end = start = i + 1
output += `if (str.charCodeAt(${this.__getIndex(indent, 0, params)}) === ${branch.char.charCodeAt(0)}) { // ${branch.char}`
if (branch.path) {
output += '\n' + indentation + ` if (str.length === ${this.__getIndex(indent, 1, params)}) {`
output += this.__treeIntoCompiledCodeReturnPath(indentation + ' ', paths, branch, params)
output += '\n' + indentation + ` }`
}
} else { } else {
addEndBracket = false end++
let paramVarName = (params.length + 1) + '_' + branch.paramVarName
output += `let s${paramVarName} = str.slice(${this.__getIndex(indent, 0, params)}${branch.isFullParams ? '' : `, str.indexOf('/', ${this.__getIndex(indent, 0, params)}) >>> 0`})`
output += '\n' + indentation + `let offset${paramVarName} = s${paramVarName}.length`
output += '\n' + indentation
params.push([branch.isParams || branch.isFullParams, paramVarName])
if (branch.isFullParams) {
output += this.__treeIntoCompiledCodeReturnPath(indentation, paths, branch, params)
} else if (branch.path) {
output += '\n' + indentation + `if (str.length === ${this.__getIndex(indent, 0, params)}) {`
output += this.__treeIntoCompiledCodeReturnPath(indentation + ' ', paths, branch, params)
output += '\n' + indentation + `}`
}
}
if (branch.children.length) {
if (branch.path) {
output += ' else '
} else {
output += '\n' + indentation + ' '
}
output += this.__treeIntoCompiledCodeBranch(paths, branch.children, indent + 1, params.slice())
}
if (addEndBracket) {
output += '\n' + indentation + '} '
} }
} }
return output if (output = this.root.children.get(__fullParamMapName)) {
} params = {
[output.fullparamName]: url.slice(1)
__treeIntoCompiledCodeClosure(paths, tree, staticList) { }
let output = 'return function RBufferStrSliceClosure(str) {' return {
if (staticList.size > 0) { handler: output.handler,
output += '\n let checkStatic = staticList.get(str)' middlewares: output.middlewares,
output += '\n if(checkStatic) {' params: params,
output += '\n return checkStatic' }
output += '\n }'
} }
if (tree.length) { return null
output += '\n ' + this.__treeIntoCompiledCodeBranch(paths, tree, 1, [])
}
output += '\n return null'
output += '\n}'
//console.log(output)
return new Function('paths', 'staticList', output)(paths, staticList)
}
compile() {
let splitPaths = this.__splitAndSortPaths(this.paths)
let tree = this.__buildTree(splitPaths.paramsPaths.slice())
this.match = this.__treeIntoCompiledCodeClosure(this.paths, tree, splitPaths.staticPaths)
}
match(url) {
this.compile()
return this.match(url)
} }
} }
@ -866,6 +754,12 @@ ctx.state.nonce = nonce;
this.patch = this.routers.PATCH.addRoute.bind(this.routers.PATCH) this.patch = this.routers.PATCH.addRoute.bind(this.routers.PATCH)
} }
_assertIsHandler(handler, name) {
if (typeof(handler) !== 'function') {
throw new Error(`${name} was called with a handler that was not a function`)
}
}
devMode() { devMode() {
this._backuperror = this._onerror = function(err, ctx) { this._backuperror = this._onerror = function(err, ctx) {
ctx.log.error(err) ctx.log.error(err)
@ -1000,25 +894,37 @@ ctx.state.nonce = nonce;
ctx.params = route.params ctx.params = route.params
let handlers = this.runHandlers(ctx, route.path.handlers, 0) if (route.middlewares.length) {
let middle = this.handleMiddleware(ctx, route.middlewares, 0)
if (handlers && handlers.then) { if (middle && middle.then) {
return handlers.then(() => { return middle.then(() => {
return route.handler(ctx)
})
.then(() => {
this.requestEnd(null, ctx)
}, err => {
this.requestEnd(err, ctx)
})
}
}
let handler = route.handler(ctx)
if (handler && handler.then) {
return handler.then(() => {
this.requestEnd(null, ctx) this.requestEnd(null, ctx)
}, err => { }, err => {
this.requestEnd(err, ctx) this.requestEnd(err, ctx)
}) })
} }
this.requestEnd(null, ctx) this.requestEnd(null, ctx)
} }
runHandlers(ctx, middles, index) { handleMiddleware(ctx, middles, index) {
for (let i = index; i < middles.length; i++) { for (let i = index; i < middles.length; i++) {
let res = middles[i](ctx) let res = middles[i](ctx)
if (res && res.then) { if (res && res.then) {
return res.then(() => { return res.then(() => {
return this.runHandlers(ctx, middles, i + 1) return this.handleMiddleware(ctx, middles, i + 1)
}) })
} }
} }
@ -1046,7 +952,7 @@ ctx.state.nonce = nonce;
return return
} }
if (ctx.body == null && !handleUsed && ctx.status === 200) { if (ctx.body === null && !handleUsed && ctx.status === 200) {
ctx.status = 204 ctx.status = 204
} }
@ -1154,12 +1060,6 @@ ctx.state.nonce = nonce;
this[`_${type}AsyncCompiled`] = func.bind(this, ...this[`_${type}Async`]) this[`_${type}AsyncCompiled`] = func.bind(this, ...this[`_${type}Async`])
} }
} }
this.routers.GET.compile()
this.routers.POST.compile()
this.routers.PUT.compile()
this.routers.DELETE.compile()
this.routers.OPTIONS.compile()
this.routers.PATCH.compile()
} }
create() { create() {
@ -1221,7 +1121,7 @@ ctx.state.nonce = nonce;
if (err) { return rej(err) } if (err) { return rej(err) }
// Waiting 0.1 second for it to close down // Waiting 0.1 second for it to close down
setTimeout(res, 100) setTimeout(function() { res() }, 100)
}) })
}) })
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,22 +1,12 @@
import { Flaska } from './flaska.mjs' import { Flaska } from './flaska.mjs'
const port = 51026 const port = 51024
const flaska = new Flaska({}, ) const flaska = new Flaska({}, )
flaska.devMode()
flaska.get('/', function(ctx) { flaska.get('/', function(ctx) {
ctx.body = { status: true } ctx.body = { status: true }
}) })
flaska.get('/:item/asdf/herp/:derp/bla', function(ctx) {
ctx.body = { item: ctx.params.item }
})
flaska.get('/a', function(ctx) {
ctx.body = { status: true }
})
flaska.get('/error', function(ctx) { flaska.get('/error', function(ctx) {
process.exit(1) process.exit(1)
}) })

View file

@ -735,16 +735,16 @@ t.describe('#compile()', function() {
}) })
}) })
t.describe('#runHandlers()', function() { t.describe('#handleMiddleware()', function() {
t.test('should work with empty array', function() { t.test('should work with empty array', function() {
let flaska = new Flaska({}, faker) let flaska = new Flaska({}, faker)
flaska.runHandlers({}, [], 0) flaska.handleMiddleware({}, [], 0)
}) })
t.test('should work with correct index', function() { t.test('should work with correct index', function() {
let checkIsTrue = false let checkIsTrue = false
let flaska = new Flaska({}, faker) let flaska = new Flaska({}, faker)
flaska.runHandlers({}, [ flaska.handleMiddleware({}, [
function() { throw new Error('should not be thrown') }, function() { throw new Error('should not be thrown') },
function() { throw new Error('should not be thrown') }, function() { throw new Error('should not be thrown') },
function() { throw new Error('should not be thrown') }, function() { throw new Error('should not be thrown') },
@ -757,7 +757,7 @@ t.describe('#runHandlers()', function() {
const assertCtx = createCtx({ a: 1 }) const assertCtx = createCtx({ a: 1 })
let checkCounter = 0 let checkCounter = 0
let flaska = new Flaska({}, faker) let flaska = new Flaska({}, faker)
flaska.runHandlers(assertCtx, [ flaska.handleMiddleware(assertCtx, [
function(ctx) { assert.strictEqual(ctx, assertCtx); checkCounter++ }, function(ctx) { assert.strictEqual(ctx, assertCtx); checkCounter++ },
function(ctx) { assert.strictEqual(ctx, assertCtx); checkCounter++ }, function(ctx) { assert.strictEqual(ctx, assertCtx); checkCounter++ },
function(ctx) { assert.strictEqual(ctx, assertCtx); checkCounter++ }, function(ctx) { assert.strictEqual(ctx, assertCtx); checkCounter++ },
@ -771,7 +771,7 @@ t.describe('#runHandlers()', function() {
const assertCtx = createCtx({ a: 1 }) const assertCtx = createCtx({ a: 1 })
let checkCounter = 0 let checkCounter = 0
let flaska = new Flaska({}, faker) let flaska = new Flaska({}, faker)
let result = flaska.runHandlers(assertCtx, [ let result = flaska.handleMiddleware(assertCtx, [
function(ctx) { assert.strictEqual(ctx, assertCtx); assert.strictEqual(checkCounter, 0); checkCounter++ }, function(ctx) { assert.strictEqual(ctx, assertCtx); assert.strictEqual(checkCounter, 0); checkCounter++ },
function(ctx) { assert.strictEqual(ctx, assertCtx); assert.strictEqual(checkCounter, 1); checkCounter++ }, function(ctx) { assert.strictEqual(ctx, assertCtx); assert.strictEqual(checkCounter, 1); checkCounter++ },
function(ctx) { return new Promise(function(res) { assert.strictEqual(ctx, assertCtx); assert.strictEqual(checkCounter, 2); checkCounter++; res() }) }, function(ctx) { return new Promise(function(res) { assert.strictEqual(ctx, assertCtx); assert.strictEqual(checkCounter, 2); checkCounter++; res() }) },
@ -793,19 +793,19 @@ t.describe('#runHandlers()', function() {
const assertError = { a: 1 } const assertError = { a: 1 }
let checkCounter = 0 let checkCounter = 0
let flaska = new Flaska({}, faker) let flaska = new Flaska({}, faker)
let err = await assert.isRejected(flaska.runHandlers({}, [ let err = await assert.isRejected(flaska.handleMiddleware({}, [
function() { }, function() { },
function() { return new Promise(function(res, rej) { rej(assertError) }) }, function() { return new Promise(function(res, rej) { rej(assertError) }) },
function() { throw new Error('should not be seen') }, function() { throw new Error('should not be seen') },
], 0)) ], 0))
assert.strictEqual(err, assertError) assert.strictEqual(err, assertError)
err = await assert.isRejected(flaska.runHandlers({}, [ err = await assert.isRejected(flaska.handleMiddleware({}, [
function() { }, function() { },
function() { return Promise.reject(assertError) }, function() { return Promise.reject(assertError) },
function() { throw new Error('should not be seen') }, function() { throw new Error('should not be seen') },
], 0)) ], 0))
assert.strictEqual(err, assertError) assert.strictEqual(err, assertError)
err = await assert.isRejected(flaska.runHandlers({}, [ err = await assert.isRejected(flaska.handleMiddleware({}, [
function() { }, function() { },
function() { return Promise.resolve() }, function() { return Promise.resolve() },
function() { throw assertError }, function() { throw assertError },

View file

@ -220,7 +220,7 @@ t.describe('#requestStart()', function() {
}), createRes()) }), createRes())
}) })
t.test('calls handlers correctly', function(cb) { t.test('calls handleMiddleware correctly', function(cb) {
const assertError = new Error('test') const assertError = new Error('test')
const assertMiddles = [1, 2] const assertMiddles = [1, 2]
const assertParams = { a: 1, b: 2 } const assertParams = { a: 1, b: 2 }
@ -231,11 +231,12 @@ t.describe('#requestStart()', function() {
flaska.routers.GET.match = function() { flaska.routers.GET.match = function() {
return { return {
path: { handlers: assertMiddles, }, handler: function() {},
middlewares: assertMiddles,
params: assertParams, params: assertParams,
} }
} }
flaska.runHandlers = function(ctx, middles, index) { flaska.handleMiddleware = function(ctx, middles, index) {
assert.strictEqual(index, 0) assert.strictEqual(index, 0)
assert.strictEqual(middles, assertMiddles) assert.strictEqual(middles, assertMiddles)
checkMiddleCtx = ctx checkMiddleCtx = ctx
@ -390,6 +391,9 @@ t.describe('#requestStart()', function() {
let flaska = new Flaska({}, faker) let flaska = new Flaska({}, faker)
flaska.get('/::path', handler) flaska.get('/::path', handler)
flaska.compile() flaska.compile()
flaska.handleMiddleware = function() {
throw new Error('should not be called')
}
flaska.requestEnd = cb.finish(function(err, ctx) { flaska.requestEnd = cb.finish(function(err, ctx) {
assert.notOk(err) assert.notOk(err)
@ -403,7 +407,7 @@ t.describe('#requestStart()', function() {
}), createRes()) }), createRes())
}) })
t.test('calls runHandlers correctly if is promise', function(cb) { t.test('calls handleMiddleware correctly if is promise', function(cb) {
const assertError = new Error('test') const assertError = new Error('test')
const assertMiddles = [1] const assertMiddles = [1]
@ -412,11 +416,11 @@ t.describe('#requestStart()', function() {
flaska.routers.GET.match = function() { flaska.routers.GET.match = function() {
return { return {
path: { handlers: function() {}, }, handler: function() {},
middlewares: assertMiddles, middlewares: assertMiddles,
} }
} }
flaska.runHandlers = function() { flaska.handleMiddleware = function() {
return Promise.resolve().then(function() { return Promise.reject(assertError) }) return Promise.resolve().then(function() { return Promise.reject(assertError) })
} }
@ -559,6 +563,10 @@ t.describe('#requestStart()', function() {
flaska.get('/::path', [], handler) flaska.get('/::path', [], handler)
flaska.compile() flaska.compile()
flaska.handleMiddleware = function() {
throw new Error('should not be called')
}
flaska.requestEnd = cb.finish(function(err, ctx) { flaska.requestEnd = cb.finish(function(err, ctx) {
assert.notOk(err) assert.notOk(err)
assert.ok(ctx) assert.ok(ctx)

View file

@ -7,7 +7,7 @@ import { setTimeout } from 'timers/promises'
import { Flaska, FormidableHandler, FileResponse } from '../flaska.mjs' import { Flaska, FormidableHandler, FileResponse } from '../flaska.mjs'
import Client from './client.mjs' import Client from './client.mjs'
const port = 51025 const port = 51024
const log = { const log = {
fatal: stub(), fatal: stub(),
error: stub(), error: stub(),

View file

@ -45,21 +45,8 @@ t.describe('#addRoute()', function() {
router.addRoute('/:test/bla', function() {}) router.addRoute('/:test/bla', function() {})
router.addRoute('/bla/bla', function() {}) router.addRoute('/bla/bla', function() {})
router.addRoute('/bla/bla/bla', function() {}) router.addRoute('/bla/bla/bla', function() {})
assert.throws(function() { router.addRoute('/:asdf', function() {}) }, /existing/) assert.throws(function() { router.addRoute('/:asdf/', function() {}) }, /param/)
assert.throws(function() { router.addRoute('/:test/asdf/:foobar', function() {}) }, /existing/) assert.throws(function() { router.addRoute('/:test/asdf/:foobar', function() {}) }, /param/)
})
t.test('fail if adding anything after a fullparam', function() {
let router = new FlaskaRouter()
assert.throws(function() { router.addRoute('/::bla/:bla', function() {}) }, /after/)
assert.throws(function() { router.addRoute('/:test/::bla/test', function() {}) }, /after/)
assert.throws(function() { router.addRoute('/::test/bla', function() {}) }, /after/)
})
t.test('should work with param and full param side by side', function() {
let router = new FlaskaRouter()
router.addRoute('/:bla', function() {})
router.addRoute('/::bla', function() {})
}) })
t.test('fail if adding multiple fullparam', function() { t.test('fail if adding multiple fullparam', function() {
@ -69,8 +56,10 @@ t.describe('#addRoute()', function() {
router.addRoute('/:test/bla', function() {}) router.addRoute('/:test/bla', function() {})
router.addRoute('/:test/::bla', function() {}) router.addRoute('/:test/::bla', function() {})
router.addRoute('/bla/bla/bla', function() {}) router.addRoute('/bla/bla/bla', function() {})
assert.throws(function() { router.addRoute('/:test/asdf/::bla', function() {}) }, /existing/) assert.throws(function() { router.addRoute('/:test/asdf/::bla/fail', function() {}) }, /full.+param/)
assert.throws(function() { router.addRoute('/:test/::bla', function() {}) }, /existing/) assert.throws(function() { router.addRoute('/:test/::bla/test', function() {}) }, /full.+param/)
assert.throws(function() { router.addRoute('/:test/:bla', function() {}) }, /full.+param/)
assert.throws(function() { router.addRoute('/::test', function() {}) }, /partial.+param/)
}) })
t.test('add route correctly', function() { t.test('add route correctly', function() {
@ -78,7 +67,39 @@ t.describe('#addRoute()', function() {
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/a/b/c', assertHandler) router.addRoute('/a/b/c', assertHandler)
let result = router.match('/a/b/c') let result = router.match('/a/b/c')
assert.strictEqual(result.path.handlers[0], assertHandler) assert.strictEqual(result.handler, assertHandler)
})
t.test('add param route correctly', function() {
let assertHandler = function() { return 1 }
let router = new FlaskaRouter()
router.addRoute('/a/:b/c', assertHandler)
assert.ok(router.root.children.get('a'))
assert.ok(router.root.children.get('a').children.get('__param'))
assert.strictEqual(router.root.children.get('a').children.get('__param').paramName, 'b')
assert.ok(router.root.children.get('a').children.get('__param').children.get('c'))
assert.strictEqual(router.root.children.get('a').children.get('__param').children.get('c').handler, assertHandler)
})
t.test('add full param route correctly', function() {
let assertHandler = function() { return 1 }
let router = new FlaskaRouter()
router.addRoute('/a/::b', assertHandler)
assert.ok(router.root.children.get('a'))
assert.ok(router.root.children.get('a').children.get('__fullparam'))
assert.strictEqual(router.root.children.get('a').children.get('__fullparam').fullparamName, 'b')
assert.strictEqual(router.root.children.get('a').children.get('__fullparam').handler, assertHandler)
})
t.test('add param route correctly', function() {
let assertHandler = function() { return 1 }
let router = new FlaskaRouter()
router.addRoute('/a/:b/c', assertHandler)
assert.ok(router.root.children.get('a'))
assert.ok(router.root.children.get('a').children.get('__param'))
assert.strictEqual(router.root.children.get('a').children.get('__param').paramName, 'b')
assert.ok(router.root.children.get('a').children.get('__param').children.get('c'))
assert.strictEqual(router.root.children.get('a').children.get('__param').children.get('c').handler, assertHandler)
}) })
t.test('support single middlewares correctly', function() { t.test('support single middlewares correctly', function() {
@ -86,10 +107,10 @@ t.describe('#addRoute()', function() {
let assertMiddleware = function() { return 1 } let assertMiddleware = function() { return 1 }
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/a', assertMiddleware, assertHandler) router.addRoute('/a', assertMiddleware, assertHandler)
let result = router.match('/a') assert.ok(router.root.children.get('a'))
assert.strictEqual(result.path.handlers.length, 2) assert.strictEqual(router.root.children.get('a').handler, assertHandler)
assert.strictEqual(result.path.handlers[0], assertMiddleware) assert.strictEqual(router.root.children.get('a').middlewares.length, 1)
assert.strictEqual(result.path.handlers[1], assertHandler) assert.strictEqual(router.root.children.get('a').middlewares[0], assertMiddleware)
}) })
t.test('support multi middlewares correctly', function() { t.test('support multi middlewares correctly', function() {
@ -98,15 +119,15 @@ t.describe('#addRoute()', function() {
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/a', [assertMiddleware], assertHandler) router.addRoute('/a', [assertMiddleware], assertHandler)
router.addRoute('/b', [assertMiddleware, assertMiddleware], assertHandler) router.addRoute('/b', [assertMiddleware, assertMiddleware], assertHandler)
let resultA = router.match('/a') assert.ok(router.root.children.get('a'))
assert.strictEqual(resultA.path.handlers.length, 2) assert.strictEqual(router.root.children.get('a').handler, assertHandler)
assert.strictEqual(resultA.path.handlers[0], assertMiddleware) assert.strictEqual(router.root.children.get('a').middlewares.length, 1)
assert.strictEqual(resultA.path.handlers[1], assertHandler) assert.strictEqual(router.root.children.get('a').middlewares[0], assertMiddleware)
let resultB = router.match('/b') assert.ok(router.root.children.get('b'))
assert.strictEqual(resultB.path.handlers.length, 3) assert.strictEqual(router.root.children.get('b').handler, assertHandler)
assert.strictEqual(resultB.path.handlers[0], assertMiddleware) assert.strictEqual(router.root.children.get('b').middlewares.length, 2)
assert.strictEqual(resultB.path.handlers[1], assertMiddleware) assert.strictEqual(router.root.children.get('b').middlewares[0], assertMiddleware)
assert.strictEqual(resultB.path.handlers[2], assertHandler) assert.strictEqual(router.root.children.get('b').middlewares[1], assertMiddleware)
}) })
}) })
@ -115,20 +136,43 @@ t.describe('#match()', function() {
let assertMatched = false let assertMatched = false
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/test', function() { assertMatched = true }) router.addRoute('/test', function() { assertMatched = true })
let result = router.match('/test').path let result = router.match('/test')
assert.strictEqual(result.handlers.length, 1) assert.ok(result.handler)
result.handlers[0]() assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true)
// Test with extra slash at the end
assertMatched = false
result = router.match('/test/')
assert.ok(result.handler)
assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true) assert.strictEqual(assertMatched, true)
}) })
t.test('return middlewares in handlers', function() {
t.test('return middlewares', function() {
let assertMatched = false let assertMatched = false
let assertMiddleware = function() { assertMatched = true } let assertMiddleware = function() { assertMatched = true }
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/test', assertMiddleware, function() { }) router.addRoute('/test', assertMiddleware, function() { })
let result = router.match('/test').path let result = router.match('/test')
assert.strictEqual(result.handlers.length, 2) assert.ok(result.handler)
result.handlers[0]() assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 1)
result.middlewares[0]()
assert.strictEqual(assertMatched, true)
// Test with extra slash at the end
assertMatched = false
result = router.match('/test/')
assert.ok(result.handler)
assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 1)
result.middlewares[0]()
assert.strictEqual(assertMatched, true) assert.strictEqual(assertMatched, true)
}) })
@ -138,8 +182,20 @@ t.describe('#match()', function() {
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/test/:id', function() { assertMatched = true }) router.addRoute('/test/:id', function() { assertMatched = true })
let result = router.match('/test/' + assertParameter) let result = router.match('/test/' + assertParameter)
assert.strictEqual(result.path.handlers.length, 1) assert.ok(result.handler)
result.path.handlers[0]() assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true)
assert.strictEqual(result.params.id, assertParameter)
// Test with extra slash at the end
assertMatched = false
result = router.match('/test/' + assertParameter + '/')
assert.ok(result.handler)
assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true) assert.strictEqual(assertMatched, true)
assert.strictEqual(result.params.id, assertParameter) assert.strictEqual(result.params.id, assertParameter)
}) })
@ -150,8 +206,20 @@ t.describe('#match()', function() {
let router = new FlaskaRouter() let router = new FlaskaRouter()
router.addRoute('/test/::id', function() { assertMatched = true }) router.addRoute('/test/::id', function() { assertMatched = true })
let result = router.match('/test/' + assertParameter) let result = router.match('/test/' + assertParameter)
assert.strictEqual(result.path.handlers.length, 1) assert.ok(result.handler)
result.path.handlers[0]() assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true)
assert.strictEqual(result.params.id, assertParameter)
// Test with extra slash at the end
assertMatched = false
result = router.match('/test/' + assertParameter + '/')
assert.ok(result.handler)
assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true) assert.strictEqual(assertMatched, true)
assert.strictEqual(result.params.id, assertParameter) assert.strictEqual(result.params.id, assertParameter)
}) })
@ -163,13 +231,15 @@ t.describe('#match()', function() {
router.addRoute('/test/:bla', assertParamFunc) router.addRoute('/test/:bla', assertParamFunc)
router.addRoute('/::id', assertFullFunc) router.addRoute('/::id', assertFullFunc)
let result = router.match('/test/123') let result = router.match('/test/123')
assert.strictEqual(result.path.handlers.length, 1) assert.strictEqual(result.handler, assertParamFunc)
assert.strictEqual(result.path.handlers[0], assertParamFunc) assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
assert.strictEqual(result.params.bla, '123') assert.strictEqual(result.params.bla, '123')
result = router.match('/test/123/asdf') result = router.match('/test/123/asdf')
assert.strictEqual(result.path.handlers.length, 1) assert.strictEqual(result.handler, assertFullFunc)
assert.strictEqual(result.path.handlers[0], assertFullFunc) assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
assert.strictEqual(result.params.id, 'test/123/asdf') assert.strictEqual(result.params.id, 'test/123/asdf')
assert.notOk(result.params.bla) assert.notOk(result.params.bla)
}) })
@ -180,8 +250,19 @@ t.describe('#match()', function() {
router.addRoute('/test/:id', function() { assertMatched = false }) router.addRoute('/test/:id', function() { assertMatched = false })
router.addRoute('/test/:id/test1', function() { }) router.addRoute('/test/:id/test1', function() { })
let result = router.match('/test/asdf/test1') let result = router.match('/test/asdf/test1')
assert.strictEqual(result.path.handlers.length, 1) assert.ok(result.handler)
result.path.handlers[0]() assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true)
assert.strictEqual(result.params.id, 'asdf')
// Test with extra slash at the end
result = router.match('/test/asdf/test1/')
assert.ok(result.handler)
assert.ok(result.middlewares)
assert.strictEqual(result.middlewares.length, 0)
result.handler()
assert.strictEqual(assertMatched, true) assert.strictEqual(assertMatched, true)
assert.strictEqual(result.params.id, 'asdf') assert.strictEqual(result.params.id, 'asdf')
}) })
@ -196,25 +277,24 @@ t.describe('#match()', function() {
router.addRoute('/foo/::path', assertFunction) router.addRoute('/foo/::path', assertFunction)
router.addRoute('/::path', assertFailFunction) router.addRoute('/::path', assertFailFunction)
assert.strictEqual(router.match('/test/123').path.handlers[0], assertFunction) assert.strictEqual(router.match('/test/123').handler, assertFunction)
assert.strictEqual(router.match('/test/asdfasdg').path.handlers[0], assertFunction) assert.strictEqual(router.match('/test/asdfasdg').handler, assertFunction)
assert.strictEqual(router.match('/test/test/sdafsda').path.handlers[0], assertFunction) assert.strictEqual(router.match('/test/test/sdafsda').handler, assertFunction)
assert.strictEqual(router.match('/test/test/sdafsda/gdfshe4/43y34/wtaw').path.handlers[0], assertFunction) assert.strictEqual(router.match('/test/test/sdafsda/gdfshe4/43y34/wtaw').handler, assertFunction)
assert.strictEqual(router.match('/foo/123').path.handlers[0], assertFunction) assert.strictEqual(router.match('/foo/123').handler, assertFunction)
assert.strictEqual(router.match('/foo/bar/baz/test').path.handlers[0], assertFunction) assert.strictEqual(router.match('/foo/bar/baz/test').handler, assertFunction)
assert.ok(router.match('/test/123/yweherher/reher/h34h34/')) assert.ok(router.match('/test/123/yweherher/reher/h34h34/'))
assert.strictEqual(router.match('/test/123/yweherher/reher/h34h34/').path.handlers[0], assertFailFunction) assert.strictEqual(router.match('/test/123/yweherher/reher/h34h34/').handler, assertFailFunction)
assert.ok(router.match('/test/foo/bar')) assert.ok(router.match('/test/foo/bar'))
assert.strictEqual(router.match('/test/foo/bar').path.handlers[0], assertFailFunction) assert.strictEqual(router.match('/test/foo/bar').handler, assertFailFunction)
assert.ok(router.match('/')) assert.ok(router.match('/'))
assert.strictEqual(router.match('/').path.handlers[0], assertFailFunction) assert.strictEqual(router.match('/').handler, assertFailFunction)
assert.ok(router.match('/something/else/goes/here')) assert.ok(router.match('/something/else/goes/here'))
assert.strictEqual(router.match('/something/else/goes/here').path.handlers[0], assertFailFunction) assert.strictEqual(router.match('/something/else/goes/here').handler, assertFailFunction)
router.addRoute('/', assertRootFunction) router.addRoute('/', assertRootFunction)
router.compile()
assert.ok(router.match('/')) assert.ok(router.match('/'))
assert.strictEqual(router.match('/').path.handlers[0], assertRootFunction) assert.strictEqual(router.match('/').handler, assertRootFunction)
}) })
t.test('return null when no match is found', function() { t.test('return null when no match is found', function() {

View file

@ -1,20 +0,0 @@
import { Flaska } from './flaska_fast.mjs'
const port = 51028
const flaska = new Flaska({}, )
flaska.get('/', function(ctx) {
ctx.body = { status: true }
})
flaska.get('/:item/asdf/herp/:derp/bla', function(ctx) {
ctx.body = { item: ctx.params.item }
})
flaska.get('/error', function(ctx) {
process.exit(1)
})
flaska.listen(port, function() {
console.log('listening on port', port)
})

View file

@ -1,20 +0,0 @@
import { Flaska } from './flaska_buffer.mjs'
const port = 51027
const flaska = new Flaska({}, )
flaska.get('/', function(ctx) {
ctx.body = { status: true }
})
flaska.get('/:item/asdf/herp/:derp/bla', function(ctx) {
ctx.body = { item: ctx.params.item }
})
flaska.get('/error', function(ctx) {
process.exit(1)
})
flaska.listen(port, function() {
console.log('listening on port', port)
})