Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(midway-web): safelyGet() #269

Merged
merged 9 commits into from
Jul 9, 2019
3 changes: 2 additions & 1 deletion packages/midway-decorator/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export type KoaMiddleware = (context: any, next: () => Promise<any>) => any;
export type KoaMiddleware <T = any> = (context: T, next: () => Promise<any>) => void;
export type KoaMiddlewareParamArray <T = any> = Array<string | KoaMiddleware<T>>
6 changes: 3 additions & 3 deletions packages/midway-decorator/src/web/controller.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { saveClassMetadata, saveModule, scope, ScopeEnum } from 'injection';
import { CONTROLLER_KEY } from '../constant';
import { KoaMiddleware } from '../interface';
import { KoaMiddlewareParamArray } from '../interface';

export interface ControllerOption {
prefix: string;
routerOptions: {
sensitive?: boolean;
middleware?: Array<string | KoaMiddleware>
middleware?: KoaMiddlewareParamArray
};
}

export function controller(prefix: string, routerOptions: {
sensitive?: boolean,
middleware?: Array<string | KoaMiddleware>
middleware?: KoaMiddlewareParamArray
} = {middleware: [], sensitive: true}
): ClassDecorator {
return (target: any) => {
Expand Down
9 changes: 5 additions & 4 deletions packages/midway-decorator/src/web/requestMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
*/
import { attachClassMetadata } from 'injection';
import { WEB_ROUTER_KEY } from '../constant';
import { KoaMiddleware } from '../interface';
import { KoaMiddlewareParamArray } from '../interface';


export interface RouterOption {
path?: string;
requestMethod: string;
routerName?: string;
method: string;
middleware?: Array<string | KoaMiddleware>;
middleware?: KoaMiddlewareParamArray;
}

export const RequestMethod = {
Expand Down Expand Up @@ -40,7 +41,7 @@ export interface RequestMappingMetadata {
[PATH_METADATA]?: string;
[METHOD_METADATA]: string;
[ROUTER_NAME_METADATA]?: string;
[ROUTER_MIDDLEWARE]?: Array<string | KoaMiddleware>;
[ROUTER_MIDDLEWARE]?: KoaMiddlewareParamArray;
}

export const RequestMapping = (
Expand Down Expand Up @@ -68,7 +69,7 @@ const createMappingDecorator = (method: string) => (
path?: string,
routerOptions: {
routerName?: string;
middleware?: Array<string | KoaMiddleware>;
middleware?: KoaMiddlewareParamArray;
} = {middleware: []}
): MethodDecorator => {
return RequestMapping({
Expand Down
8 changes: 7 additions & 1 deletion packages/midway-web/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import {Context} from 'egg'
import {EggLoaderOptions} from 'egg-core';
import {IApplicationContext} from 'injection';
import {KoaMiddleware, KoaMiddlewareParamArray} from '@midwayjs/decorator';


export type Middleware = KoaMiddleware<Context>
export type MiddlewareParamArray = KoaMiddlewareParamArray<Context>

export interface WebMiddleware {
resolve(): (context: any, next: () => Promise<any>) => any;
resolve(): Middleware;
}

export interface MidwayLoaderOptions extends EggLoaderOptions {
Expand Down
29 changes: 14 additions & 15 deletions packages/midway-web/src/loader/webLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@ import { EggRouter as Router } from '@eggjs/router';
import {
CONTROLLER_KEY,
ControllerOption,
KoaMiddleware,
PRIORITY_KEY,
RouterOption,
WEB_ROUTER_KEY,
WEB_ROUTER_PARAM_KEY,
RouterParamValue
RouterParamValue,
} from '@midwayjs/decorator';
import * as extend from 'extend2';
import * as fs from 'fs';
import { getClassMetadata, getMethodDataFromClass, getProviderId, listModule } from 'injection';
import { ContainerLoader, MidwayHandlerKey, MidwayContainer } from 'midway-core';
import * as path from 'path';
import { MidwayLoaderOptions, WebMiddleware } from '../interface';
import { Middleware, MiddlewareParamArray, MidwayLoaderOptions, WebMiddleware } from '../interface';
import { isTypeScriptEnvironment, safelyGet } from '../utils';
import { EggAppInfo } from 'egg';

Expand Down Expand Up @@ -194,8 +193,8 @@ export class MidwayWebLoader extends EggLoader {

if (newRouter) {
// implement middleware in controller
const middlewares = controllerOption.routerOptions.middleware;
await this.handlerWebMiddleware(middlewares, (middlewareImpl: KoaMiddleware) => {
const middlewares: MiddlewareParamArray | void = controllerOption.routerOptions.middleware;
await this.handlerWebMiddleware(middlewares, (middlewareImpl: Middleware) => {
newRouter.use(middlewareImpl);
});

Expand All @@ -205,10 +204,10 @@ export class MidwayWebLoader extends EggLoader {
if (webRouterInfo && typeof webRouterInfo[Symbol.iterator] === 'function') {
for (const webRouter of webRouterInfo) {
// get middleware
const middlewares = webRouter.middleware;
const methodMiddlwares = [];
const middlewares2: MiddlewareParamArray | void = webRouter.middleware;
const methodMiddlwares: Middleware[] = [];

await this.handlerWebMiddleware(middlewares, (middlewareImpl: KoaMiddleware) => {
await this.handlerWebMiddleware(middlewares2, (middlewareImpl: Middleware) => {
methodMiddlwares.push(middlewareImpl);
});

Expand Down Expand Up @@ -241,9 +240,9 @@ export class MidwayWebLoader extends EggLoader {
}


private async handlerWebMiddleware<T extends any = any>(
middlewares: T[],
handlerCallback: (ps: T | ReturnType<WebMiddleware['resolve']>) => any,
private async handlerWebMiddleware(
middlewares: MiddlewareParamArray | void,
handlerCallback: (middlewareImpl: Middleware) => void,
): Promise<void> {

if (middlewares && middlewares.length) {
Expand All @@ -252,8 +251,8 @@ export class MidwayWebLoader extends EggLoader {
// web function middleware
handlerCallback(middleware);
} else {
const middlewareImpl: WebMiddleware = await this.applicationContext.getAsync(middleware);
if (middlewareImpl && middlewareImpl.resolve) {
const middlewareImpl: WebMiddleware | void = await this.applicationContext.getAsync(middleware);
if (middlewareImpl && typeof middlewareImpl.resolve === 'function') {
handlerCallback(middlewareImpl.resolve());
}
}
Expand All @@ -280,9 +279,9 @@ export class MidwayWebLoader extends EggLoader {

/**
* wrap controller string to middleware function
* @param controllerMapping like xxxController.index
* @param controllerMapping like FooController.index
*/
public generateController(controllerMapping: string, routeArgsInfo?: RouterParamValue[]) {
public generateController(controllerMapping: string, routeArgsInfo?: RouterParamValue[]): Middleware {
const [controllerId, methodName] = controllerMapping.split('.');
return async (ctx, next) => {
const args = [ctx, next];
Expand Down
29 changes: 17 additions & 12 deletions packages/midway-web/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,31 @@ export function isTypeScriptEnvironment(): boolean {
/**
* safelyGet(['a','b'],{a: {b: 2}}) // => 2
* safelyGet(['a','b'],{c: {b: 2}}) // => undefined
* safelyGet(['a','1'],{a: {"1": 2}}) // => 2
* safelyGet(['a','1'],{a: {b: 2}}) // => undefined
* safelyGet('a.b',{a: {b: 2}}) // => 2
* safelyGet('a.b',{c: {b: 2}}) // => undefined
*/
export function safelyGet(list, obj) {
if (arguments.length === 1) { return _obj => safelyGet(list, _obj); }

if (obj === null || obj === undefined) {
return undefined;
export function safelyGet(list: string | string[], obj?: object): any {
if (arguments.length === 1) {
return (_obj: object) => safelyGet(list, _obj);
}
let willReturn = obj;
let counter = 0;

if (typeof obj === 'undefined' || typeof obj !== 'object' || obj === null) {
return void 0;
}
const pathArrValue = typeof list === 'string' ? list.split('.') : list;
let willReturn: any = obj;

while (counter < pathArrValue.length) {
if (willReturn === null || willReturn === undefined) {
return undefined;
for (const key of pathArrValue) {
if (typeof willReturn === 'undefined' || willReturn === null) {
return void 0;
}
// for willReturn is string and key is numeric string, and willReturn[offset] maybe valid string, but not expected
else if (typeof willReturn !== 'object') {
return void 0;
}
willReturn = willReturn[ pathArrValue[ counter ] ];
counter++;
willReturn = willReturn[key];
}

return willReturn;
Expand Down