4
									
								
								packages/cc-server-binding/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/cc-server-binding/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					/node_modules
 | 
				
			||||||
 | 
					/dist
 | 
				
			||||||
 | 
					/package-lock.json
 | 
				
			||||||
 | 
					/yarn.lock
 | 
				
			||||||
							
								
								
									
										11
									
								
								packages/cc-server-binding/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								packages/cc-server-binding/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					# `cc-server-binding`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> TODO: description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					const ccServerBinding = require('cc-server-binding');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: DEMONSTRATE API
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										33
									
								
								packages/cc-server-binding/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								packages/cc-server-binding/package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "name": "cc-server-binding",
 | 
				
			||||||
 | 
					    "version": "0.2.5",
 | 
				
			||||||
 | 
					    "description": "> TODO: description",
 | 
				
			||||||
 | 
					    "author": "MiaoWoo <admin@yumc.pw>",
 | 
				
			||||||
 | 
					    "homepage": "https://github.com/502647092/cc-server-parent#readme",
 | 
				
			||||||
 | 
					    "license": "ISC",
 | 
				
			||||||
 | 
					    "main": "dist/index.js",
 | 
				
			||||||
 | 
					    "publishConfig": {
 | 
				
			||||||
 | 
					        "registry": "https://repo.yumc.pw/repository/npm/"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "repository": {
 | 
				
			||||||
 | 
					        "type": "git",
 | 
				
			||||||
 | 
					        "url": "git+https://github.com/502647092/cc-server-parent.git"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "scripts": {
 | 
				
			||||||
 | 
					        "dev": "npx ts-node src/index.ts",
 | 
				
			||||||
 | 
					        "build": "rimraf dist && npx tsc",
 | 
				
			||||||
 | 
					        "test": "echo \"Error: run tests from root\" && exit 1"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "dependencies": {
 | 
				
			||||||
 | 
					        "express": "^4.17.1",
 | 
				
			||||||
 | 
					        "reflect-metadata": "^0.1.13"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "devDependencies": {
 | 
				
			||||||
 | 
					        "mocha": "^6.1.4",
 | 
				
			||||||
 | 
					        "rimraf": "^2.6.3",
 | 
				
			||||||
 | 
					        "typescript": "^3.5.1"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "bugs": {
 | 
				
			||||||
 | 
					        "url": "https://github.com/502647092/cc-server-parent/issues"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								packages/cc-server-binding/src/activation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								packages/cc-server-binding/src/activation.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					import { Container, interfaces as inversify_interfaces } from 'inversify'
 | 
				
			||||||
 | 
					import { TYPE, interfaces as express_interfaces } from 'inversify-express-utils'
 | 
				
			||||||
 | 
					import { METADATA_KEY, VAILD_TYPE } from './constants'
 | 
				
			||||||
 | 
					import { interfaces } from './interfaces'
 | 
				
			||||||
 | 
					import { getVaildMethodMetadata, getVaildControllerMetadata, getVaildModelMetadata } from './utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let handler = {
 | 
				
			||||||
 | 
					    apply: function(target: Function, thisArgument: Object, argumentsList: any[]) {
 | 
				
			||||||
 | 
					        let methodParams = getVaildMethodMetadata(target);
 | 
				
			||||||
 | 
					        let [req, res, next] = [...argumentsList.slice(-3)];
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            // loop @Valid params
 | 
				
			||||||
 | 
					            for (const param of methodParams) {
 | 
				
			||||||
 | 
					                // get function argument value
 | 
				
			||||||
 | 
					                let origin = argumentsList[param.index]
 | 
				
			||||||
 | 
					                let props = getVaildModelMetadata(param.type);
 | 
				
			||||||
 | 
					                for (const prop of props) {
 | 
				
			||||||
 | 
					                    let propValue = origin[prop.name];
 | 
				
			||||||
 | 
					                    switch (prop.type) {
 | 
				
			||||||
 | 
					                        case VAILD_TYPE.NOT_BLANK:
 | 
				
			||||||
 | 
					                            if (!propValue) {
 | 
				
			||||||
 | 
					                                throw new Error(prop.message);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case VAILD_TYPE.NOT_NULL:
 | 
				
			||||||
 | 
					                            if (propValue == undefined) {
 | 
				
			||||||
 | 
					                                throw new Error(prop.message);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        default:
 | 
				
			||||||
 | 
					                            throw new Error('Unkonw Vaild Type!')
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return target.apply(thisArgument, argumentsList);
 | 
				
			||||||
 | 
					        } catch (ex) {
 | 
				
			||||||
 | 
					            res.status(400).json({
 | 
				
			||||||
 | 
					                status: 400,
 | 
				
			||||||
 | 
					                message: ex.message
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function rebuildServer(container: Container) {
 | 
				
			||||||
 | 
					    // get all controller
 | 
				
			||||||
 | 
					    let controllers = container.getAll<express_interfaces.Controller>(TYPE.Controller)
 | 
				
			||||||
 | 
					    // for loop controllers and inject proxy to each method
 | 
				
			||||||
 | 
					    for (const controller of controllers) {
 | 
				
			||||||
 | 
					        container.rebind(TYPE.Controller)
 | 
				
			||||||
 | 
					            .to(controller.constructor as any)
 | 
				
			||||||
 | 
					            .inSingletonScope()
 | 
				
			||||||
 | 
					            .whenTargetNamed(controller.constructor.name)
 | 
				
			||||||
 | 
					            .onActivation((ctx: inversify_interfaces.Context, controller: express_interfaces.Controller) => {
 | 
				
			||||||
 | 
					                let prop = controller.constructor.prototype
 | 
				
			||||||
 | 
					                // funcs => { create: [ { index: 0, type: [Function: ExampleModel] } ] }
 | 
				
			||||||
 | 
					                let funcs = getVaildControllerMetadata(controller.constructor);
 | 
				
			||||||
 | 
					                //Reflect.getMetadata(METADATA_KEY.controllerParameter, controller.constructor);
 | 
				
			||||||
 | 
					                for (const func in funcs) {
 | 
				
			||||||
 | 
					                    Reflect.defineMetadata(METADATA_KEY.vaildMethod, funcs[func], prop[func])
 | 
				
			||||||
 | 
					                    // Define Proxy handle model vaild
 | 
				
			||||||
 | 
					                    Reflect.defineProperty(prop, func, { value: new Proxy(prop[func], handler) })
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return controller;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { rebuildServer }
 | 
				
			||||||
							
								
								
									
										10
									
								
								packages/cc-server-binding/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/cc-server-binding/src/constants.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					export const METADATA_KEY = {
 | 
				
			||||||
 | 
					    vaildModel: "cc-server-binding:vaild-model",
 | 
				
			||||||
 | 
					    vaildMethod: "cc-server-binding:vaild-method",
 | 
				
			||||||
 | 
					    vaildController: "cc-server-binding:vaild-controller"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export enum VAILD_TYPE {
 | 
				
			||||||
 | 
					    NOT_BLANK,
 | 
				
			||||||
 | 
					    NOT_NULL
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										50
									
								
								packages/cc-server-binding/src/decorators.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								packages/cc-server-binding/src/decorators.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					import 'reflect-metadata'
 | 
				
			||||||
 | 
					import { METADATA_KEY, VAILD_TYPE } from './constants';
 | 
				
			||||||
 | 
					import { getVaildControllerMetadata, getVaildModelMetadata } from './utils'
 | 
				
			||||||
 | 
					import { interfaces } from './interfaces'
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * ParameterVaild
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function Vaild(): ParameterDecorator {
 | 
				
			||||||
 | 
					    return (controller: Object, methodName: string, index: number): void => {
 | 
				
			||||||
 | 
					        var type = Reflect.getMetadata("design:paramtypes", controller, methodName)[index];
 | 
				
			||||||
 | 
					        let metadataList = getVaildControllerMetadata(controller.constructor);
 | 
				
			||||||
 | 
					        let parameterMetadataList = metadataList[methodName] || [];
 | 
				
			||||||
 | 
					        let parameterMetadata: interfaces.ParameterMetadata = {
 | 
				
			||||||
 | 
					            index: index,
 | 
				
			||||||
 | 
					            type: type
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        parameterMetadataList.unshift(parameterMetadata);
 | 
				
			||||||
 | 
					        metadataList[methodName] = parameterMetadataList;
 | 
				
			||||||
 | 
					        Reflect.defineMetadata(METADATA_KEY.vaildController, metadataList, controller.constructor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Vaild Blank String
 | 
				
			||||||
 | 
					 * @param message Error Message
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const NotBlank: (message?: string) => PropertyDecorator = vaildDecoratorFactory(VAILD_TYPE.NOT_BLANK);
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Vaild Null Param
 | 
				
			||||||
 | 
					 * @param message Error Message
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export const NotNull: (message?: string) => PropertyDecorator = vaildDecoratorFactory(VAILD_TYPE.NOT_NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function vaildDecoratorFactory(type: VAILD_TYPE): () => PropertyDecorator {
 | 
				
			||||||
 | 
					    return function(message?: string): PropertyDecorator {
 | 
				
			||||||
 | 
					        return vaildProperty(type, message);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function vaildProperty(type: VAILD_TYPE, message?: string): PropertyDecorator {
 | 
				
			||||||
 | 
					    return (model: Object, propertyKey: string) => {
 | 
				
			||||||
 | 
					        let metadataList: interfaces.PropertyMetadata[] = getVaildModelMetadata(model.constructor);
 | 
				
			||||||
 | 
					        metadataList.push({
 | 
				
			||||||
 | 
					            name: propertyKey,
 | 
				
			||||||
 | 
					            message: message || `model ${model.constructor.name} property ${propertyKey} vaild failed => ${VAILD_TYPE[type]}`,
 | 
				
			||||||
 | 
					            type: type
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        Reflect.defineMetadata(METADATA_KEY.vaildModel, metadataList, model.constructor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										4
									
								
								packages/cc-server-binding/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								packages/cc-server-binding/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					export * from './decorators'
 | 
				
			||||||
 | 
					export * from './constants';
 | 
				
			||||||
 | 
					export * from './utils'
 | 
				
			||||||
 | 
					export * from './activation'
 | 
				
			||||||
							
								
								
									
										20
									
								
								packages/cc-server-binding/src/interfaces.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/cc-server-binding/src/interfaces.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					import { VAILD_TYPE } from './constants'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace interfaces {
 | 
				
			||||||
 | 
					    export interface MethodMetadata {
 | 
				
			||||||
 | 
					        [methodName: string]: ParameterMetadata[];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export interface ParameterMetadata {
 | 
				
			||||||
 | 
					        index: number;
 | 
				
			||||||
 | 
					        type: NewableFunction;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    export interface PropertyMetadata {
 | 
				
			||||||
 | 
					        name: string;
 | 
				
			||||||
 | 
					        message: string;
 | 
				
			||||||
 | 
					        type: VAILD_TYPE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export { interfaces };
 | 
				
			||||||
							
								
								
									
										32
									
								
								packages/cc-server-binding/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								packages/cc-server-binding/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					import { METADATA_KEY } from './constants'
 | 
				
			||||||
 | 
					import { interfaces } from './interfaces'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getVaildControllerMetadata(model: Object) {
 | 
				
			||||||
 | 
					    let controllerMetadata: interfaces.MethodMetadata = Reflect.getMetadata(
 | 
				
			||||||
 | 
					        METADATA_KEY.vaildController,
 | 
				
			||||||
 | 
					        model
 | 
				
			||||||
 | 
					    ) || {};
 | 
				
			||||||
 | 
					    return controllerMetadata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getVaildMethodMetadata(constructor: any) {
 | 
				
			||||||
 | 
					    let parameterMetadata: interfaces.ParameterMetadata[] = Reflect.getMetadata(
 | 
				
			||||||
 | 
					        METADATA_KEY.vaildMethod,
 | 
				
			||||||
 | 
					        constructor
 | 
				
			||||||
 | 
					    ) || [];
 | 
				
			||||||
 | 
					    return parameterMetadata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getVaildModelMetadata(model: Object) {
 | 
				
			||||||
 | 
					    let propertyMetadata: interfaces.PropertyMetadata[] = Reflect.getMetadata(
 | 
				
			||||||
 | 
					        METADATA_KEY.vaildModel,
 | 
				
			||||||
 | 
					        model
 | 
				
			||||||
 | 
					    ) || [];
 | 
				
			||||||
 | 
					    return propertyMetadata;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					    getVaildControllerMetadata,
 | 
				
			||||||
 | 
					    getVaildMethodMetadata,
 | 
				
			||||||
 | 
					    getVaildModelMetadata
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								packages/cc-server-binding/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								packages/cc-server-binding/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "extends": "../../tsconfig.json",
 | 
				
			||||||
 | 
					    "compilerOptions": {
 | 
				
			||||||
 | 
					        "baseUrl": "src",
 | 
				
			||||||
 | 
					        "outDir": "dist"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user