Last active
January 28, 2016 18:43
-
-
Save amcdnl/318f7d91a2007656c7da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Controller, httpGet, httpPost, httpPut, httpDelete } from '../common/routing'; | |
import { authenticate } from '../common/auth'; | |
import { Application } from '../models/Application'; | |
@Controller('/app' , authenticate) // <= authentication middleware for passport | |
export default class ApplicationController { | |
appRepository: any; | |
@socket('message') <== web socket event | |
messaged(socket){ | |
console.log('message recieved!') | |
} | |
@httpGet() | |
async getAll(ctx) { | |
ctx.body = await this.appRepository.findAll(); | |
} | |
@httpPost(validate({ body: Application })) <!== validation middleware | |
async post(ctx) { | |
let app = new Application(ctx.request.body); | |
ctx.body = await this.appRepository.create(app); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Route decorators for KOA Router | |
* Stolen from: https://github.com/buunguyen/route-decorators | |
* | |
* Changes: | |
* - Added http prefix which fixed delete issue | |
* - Made it work with TypeScript | |
* - Added Socket Events | |
*/ | |
const PREFIX = '$$route_'; | |
const SOCKET_PREFIX = '$$sock_'; | |
function destruct(args) { | |
const hasPath = typeof args[0] === 'string'; | |
const path = hasPath ? args[0] : ''; | |
const middleware = hasPath ? args.slice(1) : args; | |
if (middleware.some(m => typeof m !== 'function')) { | |
throw new Error('Middleware must be function') | |
} | |
return [path, middleware]; | |
} | |
/** | |
* Route Decorator | |
* Signature: `@route(method, path: optional, ...middleware: optional)` | |
* | |
* @param {Function} method | |
* @param {Object} args | |
* @return {Function} | |
*/ | |
export function route(method, path?, m1?, m2?, m3?, m4?, m5?) { | |
if (typeof method !== 'string') { | |
throw new Error('The first argument must be an HTTP method'); | |
} | |
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | |
args[_key - 1] = arguments[_key]; | |
} | |
const destructed = destruct(args); | |
var path = destructed[0]; | |
var middleware = destructed[1]; | |
return function (target, name) { | |
target['' + PREFIX + name] = { method: method, path: path, middleware: middleware }; | |
}; | |
} | |
// @[method](...args) === @route(method, ...args) | |
const methods = ['head', 'options', 'get', 'post', 'put', 'patch', 'del', 'delete', 'all']; | |
methods.forEach(function (method) { | |
const methName = method.charAt(0).toUpperCase() + method.slice(1); | |
exports['http' + methName] = route.bind(null, method); | |
}); | |
// hack to get ^^ to work w/ TS | |
export var httpGet; | |
export var httpPost; | |
export var httpPut; | |
export var httpPatch; | |
export var httpDelete; | |
/** | |
* Socket Decorator | |
* Signature: `@socket(event)` | |
* | |
* @param {String} event | |
* @return {Function} | |
*/ | |
export function socket(event) { | |
if (typeof event !== 'string') { | |
throw new Error('The first argument must be an event name'); | |
} | |
return function (target, name) { | |
target['' + SOCKET_PREFIX + name] = { event: event }; | |
}; | |
} | |
/** | |
* Controller Decorator | |
* Signature: `@controller(path: optional, ...middleware: optional)` | |
* | |
* @param {...[Object]} args | |
*/ | |
export function Controller(path?, m1?, m2?, m3?, m4?, m5?) { | |
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | |
args[_key2] = arguments[_key2]; | |
} | |
const destructed = destruct(args); | |
const ctrlPath = destructed[0]; | |
const ctrlMiddleware = destructed[1]; | |
return function (target) { | |
target.$path = ctrlPath; | |
const proto = target.prototype; | |
proto.$routes = Object.getOwnPropertyNames(proto) | |
.filter(prop => prop.indexOf(PREFIX) === 0) | |
.map(prop => { | |
const method = proto[prop].method; | |
const path = proto[prop].path; | |
const actionMiddleware = proto[prop].middleware; | |
const url = '' + ctrlPath + path; | |
const middleware = ctrlMiddleware.concat(actionMiddleware); | |
const fnName = prop.substring(PREFIX.length); | |
return { method: method, url: url, middleware: middleware, fnName: fnName }; | |
}); | |
proto.$sockets = Object.getOwnPropertyNames(proto) | |
.filter(prop => prop.indexOf(SOCKET_PREFIX) === 0) | |
.map(prop => { | |
const event = proto[prop].event; | |
const fnName = prop.substring(PREFIX.length); | |
return { event, fnName}; | |
}); | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as glob from 'glob'; | |
import * as path from 'path'; | |
/** | |
* The filenames of all controllers. | |
* @type {Array} | |
*/ | |
export const files = | |
glob.sync(`dist/api/**/*[Controller].js`); | |
/** | |
* Static instances of the controllers. | |
* @type {Array} | |
*/ | |
export const controllers = | |
files.map(f => { | |
return require(path.resolve(f)); | |
}); | |
/** | |
* Binds the router to the controller routes | |
* @param {Object} routerRoutes | |
* @return {Object} router routes | |
*/ | |
export function bindRoutes(routerRoutes){ | |
for(let ctrl of controllers){ | |
let routes = ctrl.default.prototype.$routes; | |
for(const route of routes) { | |
let url = route.url, | |
method = route.method, | |
middleware = route.middleware, | |
fnName = route.fnName; | |
routerRoutes[method].apply(routerRoutes, [url].concat(Array.from(middleware), [function () { | |
// TS lacks object spread/rest | |
// https://github.com/Microsoft/TypeScript/issues/2103 | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
let inst = new ctrl.default(); | |
return inst[fnName](this, args); | |
}])); | |
} | |
} | |
return routerRoutes; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment