Comparing version 0.2.0 to 0.2.1
@@ -1,2 +0,2 @@ | ||
import { IMiddleware, RouterContext } from 'koa-router'; | ||
import Router, { IMiddleware, RouterContext } from 'koa-router'; | ||
export * from './src/base/controller-base'; | ||
@@ -9,2 +9,3 @@ export * from './src/decorators/actions'; | ||
export * from './src/decorators/authorized'; | ||
export * from './src/decorators/query-object'; | ||
export declare function routing(config: RouterConfig, ...controllers: Function[]): IMiddleware; | ||
@@ -22,5 +23,9 @@ export declare function routing(...controllers: Function[]): IMiddleware; | ||
/** | ||
* Init callback. Called once Router instance initialized. | ||
*/ | ||
init?: (router: Router) => void; | ||
/** | ||
* Get user role callback from user state | ||
*/ | ||
getUserRoles?: (user: any) => string[]; | ||
getUserRoles?: (user: any) => any[]; | ||
/** | ||
@@ -27,0 +32,0 @@ * Error handler callback |
"use strict"; | ||
var __spreadArrays = (this && this.__spreadArrays) || function () { | ||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; | ||
for (var r = Array(s), k = 0, i = 0; i < il; i++) | ||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) | ||
r[k] = a[j]; | ||
return r; | ||
}; | ||
function __export(m) { | ||
@@ -19,2 +26,3 @@ for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
__export(require("./src/decorators/authorized")); | ||
__export(require("./src/decorators/query-object")); | ||
function routing(args) { | ||
@@ -27,3 +35,3 @@ var controllers = []; | ||
if (typeof args === 'function') { | ||
controllers = [args].concat(controllers); | ||
controllers = __spreadArrays([args], controllers); | ||
} | ||
@@ -42,5 +50,8 @@ else { | ||
var router = new koa_router_1.default(); | ||
if (config.init) { | ||
config.init(router); | ||
} | ||
return koa_compose_1.default([ | ||
router | ||
.use.apply(router, [base].concat(controllers.map(function (ctrl) { return utils_1.getMeta(ctrl.prototype).routes(config); }))).routes(), | ||
.use.apply(router, __spreadArrays([base], controllers.map(function (ctrl) { return utils_1.getMeta(ctrl.prototype).routes(ctrl, config); }))).routes(), | ||
router.allowedMethods() | ||
@@ -47,0 +58,0 @@ ]); |
import { RouterContext } from 'koa-router'; | ||
export declare class ControllerBase { | ||
export declare class ControllerBase<TUser = any> { | ||
context: RouterContext; | ||
next: () => Promise<any>; | ||
user: TUser; | ||
} |
@@ -0,1 +1,2 @@ | ||
import { StaticSendOptions } from '../lib/action-meta'; | ||
export declare function get(route?: string | RegExp): MethodDecorator; | ||
@@ -5,1 +6,6 @@ export declare function post(route?: string | RegExp): MethodDecorator; | ||
export declare function del(route?: string | RegExp): MethodDecorator; | ||
/** | ||
* Make the method as static file server (using `koa-send`). | ||
* The method body should be empty. Since it will be ignored. | ||
*/ | ||
export declare function serve(route?: string | RegExp, options?: StaticSendOptions): MethodDecorator; |
@@ -46,2 +46,18 @@ "use strict"; | ||
exports.del = del; | ||
/** | ||
* Make the method as static file server (using `koa-send`). | ||
* The method body should be empty. Since it will be ignored. | ||
*/ | ||
function serve(route, options) { | ||
return function (root, method) { | ||
utils_1.getMeta(root).actions.push(new action_meta_1.ActionMeta({ | ||
httpMethod: types_1.HttpMethods.get, | ||
method: method, | ||
route: route, | ||
static: true, | ||
staticOptions: options | ||
})); | ||
}; | ||
} | ||
exports.serve = serve; | ||
//# sourceMappingURL=actions.js.map |
export declare function authorized(): Function; | ||
export declare function authorized(role: string): Function; | ||
export declare function authorized(roles: string[]): Function; | ||
export declare function authorized(role: string, errroMsg?: string): Function; | ||
export declare function authorized(role: any, errroMsg?: string): Function; | ||
export declare function authorized(roles: string[], errroMsg?: string): Function; | ||
export declare function authorized(fn: (user: any) => string, errroMsg?: string): Function; |
@@ -6,4 +6,6 @@ "use strict"; | ||
var utils_1 = require("../lib/utils"); | ||
function authorized(roleOrRoles) { | ||
function authorized(roleOrRoles, errroMsg) { | ||
if (errroMsg === void 0) { errroMsg = 'Insufficient access right.'; } | ||
var roles = []; | ||
var fn; | ||
if (!roleOrRoles) { | ||
@@ -15,2 +17,5 @@ roles = []; | ||
} | ||
else if (typeof roleOrRoles === 'function') { | ||
fn = roleOrRoles; | ||
} | ||
else { | ||
@@ -21,6 +26,6 @@ roles.push(roleOrRoles); | ||
if (target.prototype) { | ||
utils_1.getMeta(target.prototype).controllerAuthorizations.push(new authorized_meta_1.AuthorizedMeta(key, roles || [])); | ||
utils_1.getMeta(target.prototype).controllerAuthorizations.push(new authorized_meta_1.AuthorizedMeta(key, roles || [], errroMsg, fn)); | ||
} | ||
else { | ||
utils_1.getMeta(target).methodAuthorizations.push(new authorized_meta_1.AuthorizedMeta(key, roles || [])); | ||
utils_1.getMeta(target).methodAuthorizations.push(new authorized_meta_1.AuthorizedMeta(key, roles || [], errroMsg, fn)); | ||
} | ||
@@ -27,0 +32,0 @@ }; |
@@ -1,1 +0,2 @@ | ||
export declare function body(): ParameterDecorator; | ||
import { ValidateType } from '../types'; | ||
export declare function body(validate?: ValidateType): ParameterDecorator; |
@@ -5,5 +5,5 @@ "use strict"; | ||
var utils_1 = require("../lib/utils"); | ||
function body() { | ||
function body(validate) { | ||
return function (target, key, index) { | ||
utils_1.getMeta(target).bodyParameters.push(new body_meta_1.BodyMeta(key, index)); | ||
utils_1.getMeta(target).bodyParameters.push(new body_meta_1.BodyMeta(key, index, validate)); | ||
}; | ||
@@ -10,0 +10,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var utils_1 = require("../lib/utils"); | ||
function controller(route) { | ||
return function (target) { | ||
utils_1.getMeta(target.prototype).setTarget(target, route); | ||
target.prototype.route = route; | ||
}; | ||
@@ -8,0 +7,0 @@ } |
@@ -1,1 +0,2 @@ | ||
export declare function param(name: string): ParameterDecorator; | ||
import { ValidateType } from '../types'; | ||
export declare function param(name: string, validate?: ValidateType): ParameterDecorator; |
@@ -5,5 +5,5 @@ "use strict"; | ||
var utils_1 = require("../lib/utils"); | ||
function param(name) { | ||
function param(name, validate) { | ||
return function (target, key, index) { | ||
utils_1.getMeta(target).bodyParameters.push(new param_meta_1.ParamMeta(key, index, name)); | ||
utils_1.getMeta(target).bodyParameters.push(new param_meta_1.ParamMeta(key, index, name, validate)); | ||
}; | ||
@@ -10,0 +10,0 @@ } |
import { IMiddleware } from 'koa-router'; | ||
import { SendOptions } from 'koa-send'; | ||
import { RouterConfig } from '../..'; | ||
@@ -9,4 +10,6 @@ import { HttpMethods } from '../types'; | ||
route: string | RegExp; | ||
static?: boolean; | ||
staticOptions?: StaticSendOptions; | ||
constructor(args: ActionMetaArgs); | ||
createMiddleware(meta: ControllerMeta, clazz: Function, config: RouterConfig): IMiddleware; | ||
createMiddleware(meta: ControllerMeta, Clazz: FunctionConstructor, config: RouterConfig): IMiddleware; | ||
} | ||
@@ -17,2 +20,7 @@ export interface ActionMetaArgs { | ||
route?: string | RegExp; | ||
static?: boolean; | ||
staticOptions?: StaticSendOptions; | ||
} | ||
export declare type StaticSendOptions = SendOptions & { | ||
base?: string; | ||
}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -37,2 +38,9 @@ }); | ||
}; | ||
var __spreadArrays = (this && this.__spreadArrays) || function () { | ||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; | ||
for (var r = Array(s), k = 0, i = 0; i < il; i++) | ||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) | ||
r[k] = a[j]; | ||
return r; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -42,3 +50,5 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var koa_send_1 = __importDefault(require("koa-send")); | ||
var lodash_1 = __importDefault(require("lodash")); | ||
var path_1 = __importDefault(require("path")); | ||
var ActionMeta = /** @class */ (function () { | ||
@@ -48,2 +58,4 @@ function ActionMeta(args) { | ||
this.method = args.method; | ||
this.static = args.static; | ||
this.staticOptions = args.staticOptions; | ||
var route = args.route; | ||
@@ -67,6 +79,6 @@ if (!route) { | ||
} | ||
ActionMeta.prototype.createMiddleware = function (meta, clazz, config) { | ||
ActionMeta.prototype.createMiddleware = function (meta, Clazz, config) { | ||
var _this = this; | ||
return function (context, next) { return __awaiter(_this, void 0, void 0, function () { | ||
var params, _i, _a, baseAuth, _b, _c, authMeta, _d, error_1, onError; | ||
var clazz, params, _i, _a, baseAuth, _b, _c, authMeta, _d, error_1, onError; | ||
var _this = this; | ||
@@ -76,7 +88,9 @@ return __generator(this, function (_e) { | ||
case 0: | ||
Object.assign(clazz, { | ||
Object.assign(Clazz.prototype, { | ||
context: context, | ||
next: next | ||
next: next, | ||
user: context.state[config.userStateName || 'user'] | ||
}); | ||
params = lodash_1.default(meta.bodyParameters.filter(function (b) { return b.method === _this.method; }).concat(meta.urlParameters.filter(function (b) { return b.method === _this.method; }), meta.userParameters.filter(function (b) { return b.method === _this.method; }))) | ||
clazz = new Clazz(); | ||
params = lodash_1.default(__spreadArrays(meta.bodyParameters.filter(function (b) { return b.method === _this.method; }), meta.urlParameters.filter(function (b) { return b.method === _this.method; }), meta.queryObjectParameters.filter(function (b) { return b.method === _this.method; }), meta.userParameters.filter(function (b) { return b.method === _this.method; }))) | ||
.sortBy(function (p) { return p.index; }) | ||
@@ -97,2 +111,5 @@ .value(); | ||
} | ||
if (this.static) { | ||
return [2 /*return*/, koa_send_1.default(context, path_1.default.join((this.staticOptions && this.staticOptions.base) || '', lodash_1.default.values(context.params).join('/')))]; | ||
} | ||
_d = context; | ||
@@ -103,5 +120,3 @@ return [4 /*yield*/, clazz[this.method].apply(clazz, params.map(function (p) { return p.getValue(context, config); }))]; | ||
return [4 /*yield*/, next()]; | ||
case 3: | ||
_e.sent(); | ||
return [3 /*break*/, 8]; | ||
case 3: return [2 /*return*/, _e.sent()]; | ||
case 4: | ||
@@ -108,0 +123,0 @@ error_1 = _e.sent(); |
@@ -5,5 +5,7 @@ import { RouterContext } from 'koa-router'; | ||
roles: string[]; | ||
authorize?: (user: any) => string; | ||
method: string; | ||
constructor(method: string, roles: string[]); | ||
errorMsg: string; | ||
constructor(method: string, roles: string[], errorMsg: string, authorize?: (user: any) => string); | ||
validate(context: RouterContext, config: RouterConfig): void; | ||
} |
@@ -8,5 +8,7 @@ "use strict"; | ||
var AuthorizedMeta = /** @class */ (function () { | ||
function AuthorizedMeta(method, roles) { | ||
function AuthorizedMeta(method, roles, errorMsg, authorize) { | ||
this.method = method; | ||
this.roles = roles; | ||
this.authorize = authorize; | ||
this.errorMsg = errorMsg; | ||
} | ||
@@ -26,5 +28,11 @@ AuthorizedMeta.prototype.validate = function (context, config) { | ||
if (!userRoles.some(function (role) { return _this.roles.indexOf(role) > -1; })) { | ||
throw boom_1.default.unauthorized('Insufficient access right.'); | ||
throw boom_1.default.forbidden(this.errorMsg); | ||
} | ||
} | ||
if (this.authorize) { | ||
var result = this.authorize(user); | ||
if (typeof result === 'string') { | ||
throw boom_1.default.unauthorized(result); | ||
} | ||
} | ||
}; | ||
@@ -31,0 +39,0 @@ return AuthorizedMeta; |
import 'koa-body'; | ||
import { RouterContext } from 'koa-router'; | ||
import { IParamMeta } from '../types'; | ||
export declare class BodyMeta implements IParamMeta { | ||
import { IParamMeta, IParamValidationMeta, ValidateType } from '../types'; | ||
export declare class BodyMeta implements IParamMeta, IParamValidationMeta { | ||
/** | ||
@@ -13,4 +13,8 @@ * name of method | ||
index: number; | ||
constructor(key: string, index: number); | ||
/** | ||
* validation function/schema | ||
*/ | ||
validate?: ValidateType; | ||
constructor(key: string, index: number, validate?: ValidateType); | ||
getValue(context: RouterContext): any; | ||
} |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
require("koa-body"); | ||
var utils_1 = require("./utils"); | ||
var BodyMeta = /** @class */ (function () { | ||
function BodyMeta(key, index) { | ||
function BodyMeta(key, index, validate) { | ||
this.method = key; | ||
this.index = index; | ||
this.validate = validate; | ||
} | ||
BodyMeta.prototype.getValue = function (context) { | ||
return context.request.body; | ||
var data = context.request.body; | ||
if (context.request.files) { | ||
data = __assign(__assign({}, data), context.request.files); | ||
} | ||
return utils_1.validateValue(data, this.validate); | ||
}; | ||
@@ -12,0 +29,0 @@ return BodyMeta; |
@@ -7,6 +7,7 @@ import { IMiddleware } from 'koa-router'; | ||
import { ParamMeta } from './param-meta'; | ||
import { QueryObjectMeta } from './query-object-meta'; | ||
import { UserMeta } from './user-meta'; | ||
export declare class ControllerMeta { | ||
private target; | ||
private route; | ||
private route?; | ||
/** | ||
@@ -29,2 +30,6 @@ * Controller actions | ||
/** | ||
* Query parameters as object | ||
*/ | ||
queryObjectParameters: QueryObjectMeta[]; | ||
/** | ||
* Controller authorization | ||
@@ -40,9 +45,8 @@ */ | ||
* @param target controller class | ||
* @param route base route | ||
*/ | ||
setTarget(target: FunctionConstructor, route?: string | RegExp): void; | ||
private setTarget; | ||
/** | ||
* Build routes middleware for this controller | ||
*/ | ||
routes(config: RouterConfig): IMiddleware; | ||
routes(target: Function, config: RouterConfig): IMiddleware; | ||
} |
@@ -28,2 +28,6 @@ "use strict"; | ||
/** | ||
* Query parameters as object | ||
*/ | ||
this.queryObjectParameters = []; | ||
/** | ||
* Controller authorization | ||
@@ -40,5 +44,5 @@ */ | ||
* @param target controller class | ||
* @param route base route | ||
*/ | ||
ControllerMeta.prototype.setTarget = function (target, route) { | ||
ControllerMeta.prototype.setTarget = function (target) { | ||
var route = target.prototype.route; | ||
this.target = target; | ||
@@ -59,8 +63,10 @@ if (!route) { | ||
*/ | ||
ControllerMeta.prototype.routes = function (config) { | ||
ControllerMeta.prototype.routes = function (target, config) { | ||
var router = new koa_router_1.default(); | ||
var clazz = new this.target(); | ||
this.setTarget(target); | ||
for (var _i = 0, _a = this.actions; _i < _a.length; _i++) { | ||
var a = _a[_i]; | ||
router[a.httpMethod](a.route, koa_compose_1.default([a.createMiddleware(this, clazz, config)])); | ||
router[a.httpMethod](a.route, koa_compose_1.default([ | ||
a.createMiddleware(this, this.target, config) | ||
])); | ||
} | ||
@@ -67,0 +73,0 @@ return new koa_router_1.default().use(this.route, router.routes()).routes(); |
import { RouterContext } from 'koa-router'; | ||
import { IParamMeta } from '../types'; | ||
export declare class ParamMeta implements IParamMeta { | ||
import { IParamMeta, IParamValidationMeta, ValidateType } from '../types'; | ||
export declare class ParamMeta implements IParamMeta, IParamValidationMeta { | ||
/** | ||
@@ -16,4 +16,8 @@ * name of method | ||
index: number; | ||
constructor(key: string, index: number, name: string); | ||
/** | ||
* validation function/schema | ||
*/ | ||
validate?: ValidateType; | ||
constructor(key: string, index: number, name: string, validate?: ValidateType); | ||
getValue(context: RouterContext): any; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var utils_1 = require("./utils"); | ||
var ParamMeta = /** @class */ (function () { | ||
function ParamMeta(key, index, name) { | ||
function ParamMeta(key, index, name, validate) { | ||
this.method = key; | ||
this.index = index; | ||
this.name = name; | ||
this.validate = validate; | ||
} | ||
ParamMeta.prototype.getValue = function (context) { | ||
return context.params[this.name]; | ||
return utils_1.validateValue(context.params[this.name], this.validate); | ||
}; | ||
@@ -12,0 +14,0 @@ return ParamMeta; |
@@ -0,2 +1,4 @@ | ||
import { ValidateType } from '../types'; | ||
import { ControllerMeta } from './controller-meta'; | ||
export declare function getMeta(object: any): ControllerMeta; | ||
export declare function validateValue(value: any, validate?: ValidateType): any; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var boom_1 = __importDefault(require("@hapi/boom")); | ||
var yup_1 = require("yup"); | ||
var controller_meta_1 = require("./controller-meta"); | ||
@@ -11,2 +16,21 @@ function getMeta(object) { | ||
exports.getMeta = getMeta; | ||
function validateValue(value, validate) { | ||
if (validate) { | ||
if (typeof validate === 'function') { | ||
return validate(value); | ||
} | ||
else { | ||
try { | ||
return validate.validateSync(value); | ||
} | ||
catch (error) { | ||
if (error instanceof yup_1.ValidationError) { | ||
throw boom_1.default.badRequest(error.message); | ||
} | ||
} | ||
} | ||
} | ||
return value; | ||
} | ||
exports.validateValue = validateValue; | ||
//# sourceMappingURL=utils.js.map |
import { RouterContext } from 'koa-router'; | ||
import { Schema } from 'yup'; | ||
import { RouterConfig } from '..'; | ||
@@ -15,1 +16,5 @@ export declare enum HttpMethods { | ||
} | ||
export interface IParamValidationMeta { | ||
validate?: ValidateType; | ||
} | ||
export declare type ValidateType = Schema<any> | Function; |
{ | ||
"name": "koami", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"description": "Create typescript Koa class based controllers with decorators", | ||
@@ -17,3 +17,4 @@ "keywords": [ | ||
"scripts": { | ||
"build": "rm -rf dist && tsc" | ||
"build": "rm -rf dist && tsc", | ||
"release": "standard-version" | ||
}, | ||
@@ -24,17 +25,21 @@ "files": [ | ||
"dependencies": { | ||
"lodash": "^4.17.11" | ||
"lodash": "^4.17.11", | ||
"yup": "^0.27.0" | ||
}, | ||
"devDependencies": { | ||
"@hapi/boom": "^7.4.2", | ||
"@types/hapi__boom": "^7.4.0", | ||
"@hapi/boom": "^7.4.3", | ||
"@types/hapi__boom": "^7.4.1", | ||
"@types/koa-compose": "^3.2.4", | ||
"@types/koa-router": "^7.0.41", | ||
"@types/lodash": "^4.14.135", | ||
"koa-body": "^4.1.0", | ||
"@types/koa-router": "^7.0.42", | ||
"@types/lodash": "^4.14.138", | ||
"@types/yup": "^0.26.24", | ||
"koa-body": "^4.1.1", | ||
"koa-compose": "^4.1.0", | ||
"koa-router": "^7.4.0", | ||
"tslint": "^5.18.0", | ||
"koa-send": "^5.0.0", | ||
"standard-version": "^7.1.0", | ||
"tslint": "^5.19.0", | ||
"typedi": "^0.8.0", | ||
"typescript": "^3.5.2" | ||
"typescript": "^3.6.2" | ||
} | ||
} |
# Koami | ||
> WIP |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
47985
57
839
0
2
14
+ Addedyup@^0.27.0
+ Added@babel/runtime@7.26.9(transitive)
+ Addedfn-name@2.0.1(transitive)
+ Addedproperty-expr@1.5.1(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
+ Addedsynchronous-promise@2.0.17(transitive)
+ Addedtoposort@2.0.2(transitive)
+ Addedyup@0.27.0(transitive)