@plumier/core
Advanced tools
Comparing version 1.0.0-beta.10 to 1.0.0-beta.11
import { Context } from "koa"; | ||
import { HeaderPart, RequestPart } from "./binder"; | ||
import { GetOption } from 'cookies'; | ||
export declare namespace bind { | ||
@@ -71,2 +72,8 @@ /** | ||
/** | ||
* Bind request cookie into parameter | ||
* | ||
* method(@bind.cookie("name") cookie:string){} | ||
*/ | ||
function cookie(name: string, opt?: GetOption): (...args: any[]) => void; | ||
/** | ||
* Bind custom part of Koa context into parameter | ||
@@ -73,0 +80,0 @@ * example: |
@@ -96,2 +96,11 @@ "use strict"; | ||
/** | ||
* Bind request cookie into parameter | ||
* | ||
* method(@bind.cookie("name") cookie:string){} | ||
*/ | ||
function cookie(name, opt) { | ||
return tinspector_1.mergeDecorator(_1.val.optional(), bind.custom(ctx => ctx.cookies.get(name, opt))); | ||
} | ||
bind.cookie = cookie; | ||
/** | ||
* Bind custom part of Koa context into parameter | ||
@@ -98,0 +107,0 @@ * example: |
@@ -5,3 +5,3 @@ import { val } from "typedconverter"; | ||
export { HeaderPart, RequestPart, BindingDecorator, binder } from "./binder"; | ||
export { pipe } from "./middleware-pipeline"; | ||
export { invoke } from "./middleware-pipeline"; | ||
export { response } from "./response"; | ||
@@ -17,2 +17,2 @@ export { analyzeRoutes, generateRoutes, printAnalysis } from "./route-generator"; | ||
export { HttpStatus } from "./http-status"; | ||
export { ActionResult, Application, AuthorizeMetadataInfo, AuthorizeStore, Configuration, DefaultFacility, DependencyResolver, Facility, FileParser, FileUploadInfo, HttpMethod, HttpStatusError, Invocation, KoaMiddleware, Middleware, MiddlewareDecorator, MiddlewareUtil, PlumierApplication, PlumierConfiguration, RedirectActionResult, RouteContext, RouteInfo, ValidatorDecorator, ValidatorFunction, ValidatorInfo, ValidatorStore, ValidationError, errorMessage } from "./types"; | ||
export { ActionResult, Application, AuthorizeMetadataInfo, AuthorizeStore, Configuration, DefaultFacility, DependencyResolver, Facility, FileParser, FileUploadInfo, HttpMethod, HttpStatusError, Invocation, KoaMiddleware, Middleware, MiddlewareDecorator, MiddlewareUtil, PlumierApplication, PlumierConfiguration, RedirectActionResult, RouteContext, RouteInfo, RouteAnalyzerFunction, RouteAnalyzerIssue, ValidatorDecorator, ValidatorFunction, ValidatorInfo, ValidatorStore, ValidationError, errorMessage } from "./types"; |
@@ -11,3 +11,3 @@ "use strict"; | ||
var middleware_pipeline_1 = require("./middleware-pipeline"); | ||
exports.pipe = middleware_pipeline_1.pipe; | ||
exports.invoke = middleware_pipeline_1.invoke; | ||
var response_1 = require("./response"); | ||
@@ -14,0 +14,0 @@ exports.response = response_1.response; |
import { Context } from "koa"; | ||
import { ActionResult, Invocation, Middleware, RouteContext } from "./types"; | ||
declare class NotFoundActionInvocation implements Invocation { | ||
context: Context; | ||
constructor(context: Context); | ||
proceed(): Promise<ActionResult>; | ||
} | ||
declare class ActionInvocation implements Invocation { | ||
context: RouteContext; | ||
constructor(context: RouteContext); | ||
proceed(): Promise<ActionResult>; | ||
} | ||
declare function pipe(middlewares: Middleware[], context: Context, invocation: Invocation): Promise<void>; | ||
export { pipe, ActionInvocation, NotFoundActionInvocation }; | ||
import { ActionResult, RouteInfo } from "./types"; | ||
declare function pipe(ctx: Context, route?: RouteInfo, caller?: "system" | "invoke"): Promise<ActionResult>; | ||
declare function invoke(ctx: Context, route: RouteInfo): Promise<ActionResult>; | ||
export { invoke, pipe }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const types_1 = require("./types"); | ||
function getMiddleware(global, route) { | ||
const conMdws = types_1.MiddlewareUtil.extractDecorators(route); | ||
const result = []; | ||
for (const mdw of global) { | ||
result.push(mdw); | ||
} | ||
for (const mdw of conMdws) { | ||
result.push(mdw); | ||
} | ||
return result; | ||
} | ||
class MiddlewareInvocation { | ||
@@ -22,14 +33,13 @@ constructor(middleware, context, next) { | ||
} | ||
exports.NotFoundActionInvocation = NotFoundActionInvocation; | ||
class ActionInvocation { | ||
constructor(context) { | ||
constructor(context, route) { | ||
this.context = context; | ||
this.route = route; | ||
} | ||
async proceed() { | ||
const route = this.context.route; | ||
const config = this.context.config; | ||
const controller = config.dependencyResolver.resolve(route.controller.type); | ||
const result = controller[route.action.name].apply(controller, this.context.parameters); | ||
const controller = config.dependencyResolver.resolve(this.route.controller.type); | ||
const result = controller[this.route.action.name].apply(controller, this.context.parameters); | ||
const awaitedResult = await Promise.resolve(result); | ||
const status = config.responseStatus && config.responseStatus[route.method] || 200; | ||
const status = config.responseStatus && config.responseStatus[this.route.method] || 200; | ||
//if instance of action result, return immediately | ||
@@ -45,5 +55,15 @@ if (awaitedResult && awaitedResult.execute) { | ||
} | ||
exports.ActionInvocation = ActionInvocation; | ||
async function pipe(middlewares, context, invocation) { | ||
let invocationStack = invocation; | ||
function pipe(ctx, route, caller = "system") { | ||
const context = ctx; | ||
context.state.caller = caller; | ||
let middlewares; | ||
let invocationStack; | ||
if (!!route) { | ||
middlewares = getMiddleware(context.config.middlewares, route); | ||
invocationStack = new ActionInvocation(context, route); | ||
} | ||
else { | ||
middlewares = context.config.middlewares.slice(0); | ||
invocationStack = new NotFoundActionInvocation(context); | ||
} | ||
for (let i = middlewares.length; i--;) { | ||
@@ -53,5 +73,8 @@ const mdw = middlewares[i]; | ||
} | ||
const result = await invocationStack.proceed(); | ||
await result.execute(context); | ||
return invocationStack.proceed(); | ||
} | ||
exports.pipe = pipe; | ||
function invoke(ctx, route) { | ||
return pipe(ctx, route, "invoke"); | ||
} | ||
exports.invoke = invoke; |
import { Class } from "./common"; | ||
import { HttpMethod, RouteInfo } from "./types"; | ||
import { HttpMethod, RouteInfo, RouteAnalyzerIssue, RouteAnalyzerFunction } from "./types"; | ||
interface RouteDecorator { | ||
@@ -15,13 +15,9 @@ name: "Route"; | ||
} | ||
interface Issue { | ||
type: "error" | "warning" | "success"; | ||
message?: string; | ||
} | ||
interface TestResult { | ||
route: RouteInfo; | ||
issues: Issue[]; | ||
issues: RouteAnalyzerIssue[]; | ||
} | ||
declare function generateRoutes(executionPath: string, controller: string | Class[] | Class): RouteInfo[]; | ||
declare function analyzeRoutes(routes: RouteInfo[]): TestResult[]; | ||
declare function analyzeRoutes(routes: RouteInfo[], extensions?: RouteAnalyzerFunction[]): TestResult[]; | ||
declare function printAnalysis(results: TestResult[]): void; | ||
export { analyzeRoutes, generateRoutes, printAnalysis, RouteDecorator, IgnoreDecorator, RootDecorator }; |
@@ -25,5 +25,10 @@ "use strict"; | ||
} | ||
function getControllerRoute(controller) { | ||
const root = controller.decorators.filter((x) => x.name == "Root"); | ||
return root.length > 0 ? root.slice().reverse().map(x => x.url) : [`/${striveController(controller.name)}`]; | ||
function getControllerRoutes(root, controller) { | ||
const decs = controller.decorators.filter((x) => x.name == "Root"); | ||
if (decs.length > 0) { | ||
return decs.slice().reverse().map(x => transformDecorator(root, "", x)); | ||
} | ||
else { | ||
return [createRoute(root, striveController(controller.name))]; | ||
} | ||
} | ||
@@ -76,11 +81,10 @@ function getActionName(route) { | ||
return []; | ||
const controllerRoutes = getControllerRoute(controller); | ||
const controllerRoutes = getControllerRoutes(opt && opt.root || "", controller); | ||
const infos = []; | ||
for (const ctl of controllerRoutes) { | ||
const root = createRoute(opt && opt.root || "", ctl); | ||
for (const method of controller.methods) { | ||
if (method.decorators.some((x) => x.name == "Ignore" || x.name == "Route")) | ||
infos.push(...transformMethodWithDecorator(root, controller, method)); | ||
infos.push(...transformMethodWithDecorator(ctl, controller, method)); | ||
else | ||
infos.push(...transformMethod(root, controller, method)); | ||
infos.push(...transformMethod(ctl, controller, method)); | ||
} | ||
@@ -222,3 +226,3 @@ } | ||
} | ||
function analyzeRoutes(routes) { | ||
function analyzeRoutes(routes, extensions = []) { | ||
const tests = [ | ||
@@ -229,3 +233,3 @@ backingParameterTest, metadataTypeTest, | ||
]; | ||
return routes.map(x => analyzeRoute(x, tests, routes)); | ||
return routes.map(x => analyzeRoute(x, tests.concat(extensions), routes)); | ||
} | ||
@@ -232,0 +236,0 @@ exports.analyzeRoutes = analyzeRoutes; |
import { Context } from "koa"; | ||
import { Middleware, RouteInfo } from "./types"; | ||
declare function router(infos: RouteInfo[], globalMiddleware: Middleware[]): (ctx: Context) => Promise<void>; | ||
import { Configuration, RouteInfo } from "./types"; | ||
declare function router(infos: RouteInfo[], config: Configuration): (ctx: Context) => Promise<void>; | ||
export { router }; |
@@ -6,4 +6,4 @@ "use strict"; | ||
const tinspector_1 = require("tinspector"); | ||
const middleware_pipeline_1 = require("./middleware-pipeline"); | ||
const types_1 = require("./types"); | ||
const middleware_pipeline_1 = require("./middleware-pipeline"); | ||
// --------------------------------------------------------------------- // | ||
@@ -25,13 +25,2 @@ // ------------------------------- HELPER ------------------------------ // | ||
} | ||
function getMiddleware(global, route) { | ||
const conMdws = types_1.MiddlewareUtil.extractDecorators(route); | ||
const result = []; | ||
for (const mdw of global) { | ||
result.push(mdw); | ||
} | ||
for (const mdw of conMdws) { | ||
result.push(mdw); | ||
} | ||
return result; | ||
} | ||
function sendError(ctx, status, message) { | ||
@@ -44,9 +33,9 @@ ctx.status = status; | ||
/* ------------------------------------------------------------------------------- */ | ||
function router(infos, globalMiddleware) { | ||
function router(infos, config) { | ||
const matchCache = new Map(); | ||
const middlewareCache = new Map(); | ||
const getMatcherCached = tinspector_1.useCache(matchCache, getMatcher, (info, ctx) => `${ctx.method}${ctx.path}`); | ||
const getMiddlewareCached = tinspector_1.useCache(middlewareCache, getMiddleware, (global, route) => route.url); | ||
return async (ctx) => { | ||
try { | ||
ctx.config = config; | ||
ctx.routes = infos; | ||
const match = getMatcherCached(infos, ctx); | ||
@@ -59,8 +48,5 @@ if (match) { | ||
ctx.route = match.route; | ||
const middlewares = getMiddlewareCached(globalMiddleware, match.route); | ||
await middleware_pipeline_1.pipe(middlewares, ctx, new middleware_pipeline_1.ActionInvocation(ctx)); | ||
} | ||
else { | ||
await middleware_pipeline_1.pipe(globalMiddleware.slice(0), ctx, new middleware_pipeline_1.NotFoundActionInvocation(ctx)); | ||
} | ||
const result = await middleware_pipeline_1.pipe(ctx, ctx.route); | ||
await result.execute(ctx); | ||
} | ||
@@ -67,0 +53,0 @@ catch (e) { |
@@ -6,2 +6,3 @@ import Koa, { Context } from "koa"; | ||
import { HttpStatus } from "./http-status"; | ||
import { SetOption } from 'cookies'; | ||
export declare class ActionResult { | ||
@@ -12,5 +13,7 @@ body?: any; | ||
private readonly headers; | ||
private readonly cookies; | ||
constructor(body?: any, status?: number | undefined); | ||
setHeader(key: string, value: string | string[]): this; | ||
setStatus(status: number): this; | ||
setCookie(key: string, value?: string, option?: SetOption): this; | ||
execute(ctx: Context): Promise<void>; | ||
@@ -31,2 +34,7 @@ } | ||
} | ||
export interface RouteAnalyzerIssue { | ||
type: "error" | "warning" | "success"; | ||
message?: string; | ||
} | ||
export declare type RouteAnalyzerFunction = (route: RouteInfo, allRoutes: RouteInfo[]) => RouteAnalyzerIssue; | ||
export interface Facility { | ||
@@ -47,5 +55,9 @@ setup(app: Readonly<PlumierApplication>): void; | ||
route?: Readonly<RouteInfo>; | ||
routes: RouteInfo[]; | ||
config: Readonly<Configuration>; | ||
parameters?: any[]; | ||
} | ||
interface DefaultState { | ||
caller: "system" | "invoke"; | ||
} | ||
} | ||
@@ -141,2 +153,3 @@ export interface RouteContext extends Context { | ||
parent?: { | ||
value: any; | ||
type: Class; | ||
@@ -179,2 +192,6 @@ decorators: any[]; | ||
/** | ||
* List of registered global middlewares | ||
*/ | ||
middlewares: Middleware[]; | ||
/** | ||
* Specify controller path (absolute or relative to entry point) or the controller classes array. | ||
@@ -208,5 +225,5 @@ */ | ||
authorizer?: AuthorizeStore; | ||
analyzers?: RouteAnalyzerFunction[]; | ||
} | ||
export interface PlumierConfiguration extends Configuration { | ||
middleware: Middleware[]; | ||
facilities: Facility[]; | ||
@@ -213,0 +230,0 @@ } |
@@ -12,2 +12,3 @@ "use strict"; | ||
this.headers = {}; | ||
this.cookies = []; | ||
} | ||
@@ -25,2 +26,6 @@ static fromContext(ctx) { | ||
} | ||
setCookie(key, value, option) { | ||
this.cookies.push({ key, value, option }); | ||
return this; | ||
} | ||
async execute(ctx) { | ||
@@ -30,6 +35,12 @@ Object.keys(this.headers).forEach(x => { | ||
}); | ||
if (this.status) | ||
ctx.status = this.status; | ||
for (const cookie of this.cookies) { | ||
if (!cookie.value) | ||
ctx.cookies.set(cookie.key); | ||
else | ||
ctx.cookies.set(cookie.key, cookie.value, cookie.option); | ||
} | ||
if (this.body) | ||
ctx.body = this.body; | ||
if (this.status) | ||
ctx.status = this.status; | ||
} | ||
@@ -36,0 +47,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { ActionResult, Configuration, Invocation, Middleware, ValidatorFunction } from "./types"; | ||
import { ActionResult, Invocation, Middleware, ValidatorFunction } from "./types"; | ||
declare module "typedconverter" { | ||
@@ -8,6 +8,5 @@ namespace val { | ||
declare class ValidationMiddleware implements Middleware { | ||
private config; | ||
constructor(config: Configuration); | ||
constructor(); | ||
execute(invocation: Readonly<Invocation>): Promise<ActionResult>; | ||
} | ||
export { ValidationMiddleware }; |
@@ -76,8 +76,5 @@ "use strict"; | ||
class ValidationMiddleware { | ||
constructor(config) { | ||
this.config = config; | ||
} | ||
constructor() { } | ||
async execute(invocation) { | ||
const ctx = invocation.context; | ||
ctx.config = this.config; | ||
if (!ctx.route) | ||
@@ -84,0 +81,0 @@ return invocation.proceed(); |
{ | ||
"name": "@plumier/core", | ||
"version": "1.0.0-beta.10", | ||
"version": "1.0.0-beta.11", | ||
"description": "Delightful Node.js Rest Framework", | ||
@@ -29,3 +29,3 @@ "main": "lib/index.js", | ||
"tslib": "^1.10.0", | ||
"typedconverter": "^1.0.1" | ||
"typedconverter": "^1.0.4" | ||
}, | ||
@@ -42,3 +42,3 @@ "bugs": { | ||
}, | ||
"gitHead": "1ab6337771fbe7949a45f45102dd24924c631e7b", | ||
"gitHead": "e8027135a2f8f935cafbab713d2df8f7ba62ea7e", | ||
"devDependencies": { | ||
@@ -45,0 +45,0 @@ "upath": "^1.2.0" |
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
121372
2778
0
Updatedtypedconverter@^1.0.4