-
Notifications
You must be signed in to change notification settings - Fork 0
/
Kless.js
84 lines (68 loc) · 2.66 KB
/
Kless.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const path = require('path')
const assert = require('assert')
const Koa = require('@nswbmw/koa')
const compose = require('koa-compose')
const objectPath = require('object-path')
const AJS = require('another-json-schema')
const requireDirectory = require('require-directory')
const validatorMiddleware = require('./middleware/validator')
module.exports = class Kless extends Koa {
constructor () {
super()
this.middleware('validator', validatorMiddleware)
}
load (fileOrDirPath) {
if (fileOrDirPath.match(/\.js$/)) {
// file
if (path.isAbsolute(fileOrDirPath)) {
require(fileOrDirPath)
} else {
require(path.join(path.dirname(module.parent.filename), fileOrDirPath))
}
} else {
// dir
if (path.isAbsolute(fileOrDirPath)) {
requireDirectory(module, fileOrDirPath)
} else {
requireDirectory(module, path.join(path.dirname(module.parent.filename), fileOrDirPath))
}
}
}
middleware (name, fn) {
assert(name && typeof name === 'string', 'middleware `name` required')
assert(fn && (['object', 'function'].includes(typeof fn)), 'middleware second parameter should be a function or an object')
objectPath.set(this.middleware, name, fn)
}
route (obj) {
assert(typeof obj === 'object', 'route option should be an object')
assert(typeof obj.name === 'string', 'route `name` required')
assert(typeof obj.controller === 'function' || (Array.isArray(obj.controller) && obj.controller.every(ctr => typeof ctr === 'function')), 'route `controller` should be a function or an array of functions')
const controllerFnArr = Array.isArray(obj.controller) ? obj.controller : [obj.controller]
controllerFnArr.unshift(async function (ctx, next) {
ctx.routeName = obj.name
return next()
})
this.route[obj.name] = compose(controllerFnArr)
this.use((ctx, next) => {
const fn = this.route[ctx.path.slice(1) || 'index']
if (fn && typeof fn === 'function') {
return fn(ctx, next)
}
return next()
})
}
controller (name, obj) {
assert(name && typeof name === 'string', 'controller `name` required')
assert(obj && (['object', 'function'].includes(typeof obj)), 'controller second parameter should be a function or an object')
objectPath.set(this.controller, name, obj)
}
service (name, obj) {
assert(name && typeof name === 'string', 'service `name` required')
assert(obj && (['object', 'function'].includes(typeof obj)), 'service second parameter should be a function or an object')
objectPath.set(this.service, name, obj)
}
get Types () {
return AJS.Types
}
}
module.exports.Types = AJS.Types