diff --git a/.gitignore b/.gitignore index 8198112..68fa946 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ dist/ **/.vscode .idea yarn.lock +.yarnclean npm-debug.log \ No newline at end of file diff --git a/package.json b/package.json index 59f6f45..6a1557c 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "clean": "./node_modules/.bin/rimraf ./dist", "prepublish": "yarn run build", "postpublish": "./node_modules/.bin/greenkeeper-postpublish", - "start": "set NODE_ENV=development && ./node_modules/.bin/webpack-dashboard -- ./node_modules/.bin/webpack-dev-server --open --progress --config ./config/webpack/webpack.config.dev.js", + "start": "set NODE_ENV=development && ./node_modules/.bin/webpack-dev-server --open --progress --config ./config/webpack/webpack.config.dev.js", + "start:dashboard": "set NODE_ENV=development && ./node_modules/.bin/webpack-dashboard -- ./node_modules/.bin/webpack-dev-server --open --progress --config ./config/webpack/webpack.config.dev.js", "test": "yarn run jest", "test:watch": "yarn run jest -- --watch", "jest": "PWD=$(pwd) NODE_ENV=test ./node_modules/.bin/jest -w 1 --coverage", diff --git a/src/ts/@overflow/app/config/AppConfig.ts b/src/ts/@overflow/app/config/AppConfig.ts new file mode 100644 index 0000000..16e25e7 --- /dev/null +++ b/src/ts/@overflow/app/config/AppConfig.ts @@ -0,0 +1,15 @@ +import Configuration from '@overflow/commons/context/decorator/Configuration'; +import Pouch from '@overflow/commons/context/decorator/Pouch'; +import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC'; + + +@Configuration +class AppConfig { + /** + * setWebsocket + */ + @Pouch() + public setWebsocket(): WebSocketRPC { + return null; + } +} diff --git a/src/ts/@overflow/app/index.tsx b/src/ts/@overflow/app/index.tsx index 4958841..caa701a 100644 --- a/src/ts/@overflow/app/index.tsx +++ b/src/ts/@overflow/app/index.tsx @@ -80,7 +80,7 @@ class Application { this.history = createHashHistory(); } - public static Run(): void { + public static main(): void { let application = new Application(); application.start(); } @@ -245,4 +245,4 @@ class Application { } -Application.Run(); +Application.main(); diff --git a/src/ts/@overflow/app/views/layout/AccountLayout.tsx b/src/ts/@overflow/app/views/layout/AccountLayout.tsx index 46165b2..148571f 100644 --- a/src/ts/@overflow/app/views/layout/AccountLayout.tsx +++ b/src/ts/@overflow/app/views/layout/AccountLayout.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { RouteComponentProps, RouteProps, Route, Switch, } from 'react-router-dom'; +import { RouteComponentProps, RouteProps, Route, Switch } from 'react-router-dom'; import { Header, Grid, diff --git a/src/ts/@overflow/commons/context/AppContext.ts b/src/ts/@overflow/commons/context/AppContext.ts index 323e271..230b98a 100644 --- a/src/ts/@overflow/commons/context/AppContext.ts +++ b/src/ts/@overflow/commons/context/AppContext.ts @@ -1,7 +1,5 @@ +import * as CoreConstants from '@overflow/commons/core/constants'; import PouchFactory from './pouches/factory/PouchFactory'; -import { - ClassConstructor, -} from './pouches/constants'; class AppContext { private static _instance: AppContext; @@ -18,14 +16,14 @@ class AppContext { /** * getPouch */ - public getPouch(type: ClassConstructor, ...args: any[]): T { + public getPouch(type: CoreConstants.Newable, ...args: any[]): T { return this._pouchFactory.getPouch(type, args); } /** * getPouchByQualifier */ - public getPouchByQualifier(type: ClassConstructor, qualifier: string | symbol, ...args: any[]): T { + public getPouchByQualifier(type: CoreConstants.Newable, qualifier: string | symbol, ...args: any[]): T { return this._pouchFactory.getPouchByQualifier(type, qualifier, args); } diff --git a/src/ts/@overflow/commons/context/config/ConfigurationDefinition.ts b/src/ts/@overflow/commons/context/config/ConfigurationDefinition.ts new file mode 100644 index 0000000..8f5d8c3 --- /dev/null +++ b/src/ts/@overflow/commons/context/config/ConfigurationDefinition.ts @@ -0,0 +1,46 @@ +import { POUCH_DEFAULT_QUALIFIER } from '../pouches/constants'; +import PouchConfig from '../decorator/PouchConfig'; +import * as CoreConstants from '@overflow/commons/core/constants'; + +class ConfigurationDefinition { + protected _type: Function; + protected _qualifier: string | symbol = undefined; + protected _pouchMap: Map; + + public constructor(type: Function) { + this._type = type; + this._qualifier = POUCH_DEFAULT_QUALIFIER; + } + + public get type(): Function { + return this._type; + } + + public get qualifier(): string | symbol { + return this._qualifier; + } + + public set qualifier(qualifier: string | symbol) { + this._qualifier = qualifier; + } + + public addPouch(propertyKey: string, pouchConfig: PouchConfig): void { + if (undefined === this._pouchMap) { + this._pouchMap = new Map(); + } + let returnType: any = Reflect.getMetadata(CoreConstants.DESIGN_RETURNTYPE, this._type, propertyKey); + + if (undefined === pouchConfig.type) { + pouchConfig.type = returnType; + } + + this._pouchMap.set(propertyKey, pouchConfig); + } + + public get Pouches(): Map { + return this._pouchMap; + } + +} + +export default ConfigurationDefinition; diff --git a/src/ts/@overflow/commons/context/constants/index.ts b/src/ts/@overflow/commons/context/constants/index.ts new file mode 100644 index 0000000..1bc69c4 --- /dev/null +++ b/src/ts/@overflow/commons/context/constants/index.ts @@ -0,0 +1 @@ +export * from './reflect'; diff --git a/src/ts/@overflow/commons/context/constants/reflect.ts b/src/ts/@overflow/commons/context/constants/reflect.ts new file mode 100644 index 0000000..71986a5 --- /dev/null +++ b/src/ts/@overflow/commons/context/constants/reflect.ts @@ -0,0 +1,2 @@ +export const CONTEXT_CONFIGURATION_DEFINITION = 'overflow:context/configuration_definition'; +export const CONTEXT_POUCH_DEFINITION = 'overflow:context/pouch_definition'; diff --git a/src/ts/@overflow/commons/context/decorator/Configuration.ts b/src/ts/@overflow/commons/context/decorator/Configuration.ts new file mode 100644 index 0000000..699888f --- /dev/null +++ b/src/ts/@overflow/commons/context/decorator/Configuration.ts @@ -0,0 +1,20 @@ +import ConfigurationDefinition from '../config/ConfigurationDefinition'; + +import createDecorator from '../../util/decorators/createDecorator'; +import { getConfigurationDefinition } from '../util/metadata'; + +const Configuration = createDecorator('Configuration', { + classDecorator: (target: TFunction): TFunction | void => { + let configurationDefinition: ConfigurationDefinition = getConfigurationDefinition(target, false); + if (undefined !== configurationDefinition) { + throw new Error('Cannot apply @Configuration decorator multiple times.'); + } + + configurationDefinition = getConfigurationDefinition(target, true); + + return target; + }, + +}); + +export default Configuration; diff --git a/src/ts/@overflow/commons/context/decorator/Pouch.ts b/src/ts/@overflow/commons/context/decorator/Pouch.ts new file mode 100644 index 0000000..b9de612 --- /dev/null +++ b/src/ts/@overflow/commons/context/decorator/Pouch.ts @@ -0,0 +1,21 @@ +import PouchConfig from './PouchConfig'; +import ConfigurationDefinition from '../config/ConfigurationDefinition'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; + +import { getConfigurationDefinition } from '../util/metadata'; + + +const Pouch = (pouchConfig: PouchConfig = {}) => createDecorator('Pouch', { + methodDecorator: (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { + let configurationDefinition: ConfigurationDefinition = getConfigurationDefinition(target, false); + if (undefined === configurationDefinition) { + throw new Error('Cannot apply @Pouch decorator on the not @Configuration class.'); + } + + configurationDefinition.addPouch(propertyKey, pouchConfig); + + return descriptor; + }, +}); + +export default Pouch; diff --git a/src/ts/@overflow/commons/context/decorator/PouchConfig.ts b/src/ts/@overflow/commons/context/decorator/PouchConfig.ts new file mode 100644 index 0000000..d7c660c --- /dev/null +++ b/src/ts/@overflow/commons/context/decorator/PouchConfig.ts @@ -0,0 +1,6 @@ +interface PouchConfig { + qualifier?: string | symbol; + type?: any; +} + +export default PouchConfig; diff --git a/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts b/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts index 1d4b442..97febdf 100644 --- a/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts +++ b/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts @@ -1,18 +1,18 @@ import { PouchScope, POUCH_DEFAULT_QUALIFIER } from '../constants'; class PouchDefinition { - protected _type: Function; + protected _type: Object; protected _scope: PouchScope = PouchScope.SINGLETON; - protected _qualifier: string | symbol; - protected _postConstruct: string[] = null; - protected _preDestroy: string[] = null; + protected _qualifier: string | symbol = undefined; + protected _postConstruct: Set = undefined; + protected _preDestroy: Set = undefined; - public constructor(type: Function) { + public constructor(type: Object) { this._type = type; this._qualifier = POUCH_DEFAULT_QUALIFIER; } - public get type(): Function { + public get type(): Object { return this._type; } @@ -32,26 +32,26 @@ class PouchDefinition { this._qualifier = qualifier; } - public get postConstruct(): string[] { + public get postConstruct(): Set { return this._postConstruct; } public addPostConstruct(postConstruct: string): void { - if (null == this._postConstruct) { - this._postConstruct = []; + if (undefined === this._postConstruct) { + this._postConstruct = new Set(); } - this._postConstruct.push(postConstruct); + this._postConstruct.add(postConstruct); } - public get preDestroy(): string[] { + public get preDestroy(): Set { return this._preDestroy; } public addPreDestroy(preDestroy: string): void { - if (null == this._preDestroy) { - this._preDestroy = []; + if (undefined === this._preDestroy) { + this._preDestroy = new Set(); } - this._preDestroy.push(preDestroy); + this._preDestroy.add(preDestroy); } } diff --git a/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts b/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts index b93585c..3efa136 100644 --- a/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts +++ b/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts @@ -1,9 +1,10 @@ import * as METADATA from '../constants'; -import { DecoratorType, POUCH_DEFAULT_QUALIFIER } from '../constants'; +import { POUCH_DEFAULT_QUALIFIER } from '../constants'; import InjectConfig from '../decorator/InjectConfig'; +import * as CoreConstants from '@overflow/commons/core/constants'; export interface InjectItem { - decoratorType: DecoratorType; + decoratorType: CoreConstants.DecoratorType; propertyConfig?: InjectConfig; parameterConfigMap?: Map; } @@ -41,7 +42,7 @@ class PouchInjectDefinition { private addInjectParameter(injectConfig: InjectConfig, propertyKey: string | symbol, parameterIndex: number): void { let injectItem: InjectItem; - let parameterTypes: any[] = Reflect.getMetadata(METADATA.DESIGN_PARAMTYPES, this.target, propertyKey); + let parameterTypes: any[] = Reflect.getMetadata(CoreConstants.DESIGN_PARAMTYPES, this.target, propertyKey); if (undefined === injectConfig.type) { injectConfig.type = parameterTypes[parameterIndex]; @@ -51,7 +52,7 @@ class PouchInjectDefinition { injectItem = this.injectMap.get(propertyKey); } else { injectItem = { - decoratorType: DecoratorType.PARAMETER, + decoratorType: CoreConstants.DecoratorType.PARAMETER, }; this.injectMap.set(propertyKey, injectItem); } @@ -73,14 +74,14 @@ class PouchInjectDefinition { throw new Error(`Cannot apply @inject decorator on one property[${propertyKey}] multiple times.`); } - let propertyType: any = Reflect.getMetadata(METADATA.DESIGN_TYPE, this.target, propertyKey); + let propertyType: any = Reflect.getMetadata(CoreConstants.DESIGN_TYPE, this.target, propertyKey); if (undefined === injectConfig.type) { injectConfig.type = propertyType; } let injectItem: InjectItem = { - decoratorType: DecoratorType.PROPERTY, + decoratorType: CoreConstants.DecoratorType.PROPERTY, propertyConfig: injectConfig, }; diff --git a/src/ts/@overflow/commons/context/pouches/constants.ts b/src/ts/@overflow/commons/context/pouches/constants.ts deleted file mode 100644 index 556759d..0000000 --- a/src/ts/@overflow/commons/context/pouches/constants.ts +++ /dev/null @@ -1,29 +0,0 @@ -// used to access design time types -export const DESIGN_TYPE = 'design:type'; -// used to access design time types -export const DESIGN_PARAMTYPES = 'design:paramtypes'; -// used to access design time types -export const DESIGN_RETURNTYPE = 'design:returntype'; - - -// used to store types to be injected -export const POUCH_DEFINITION = 'loafer:pouch_definition'; - -// used to store types to be injected -export const POUCH_INJECT_DEFINITION = 'loafer:pouch_inject_definition'; - -export const POUCH_DEFAULT_QUALIFIER = Symbol('__QUALIFIER__'); - -export enum PouchScope { - SINGLETON, - PROTOTYPE, -} - -export enum DecoratorType { - CLASS, - PROPERTY, - PARAMETER, - METHOD, -} - -export type ClassConstructor = {new(...args: any[]): T}; diff --git a/src/ts/@overflow/commons/context/pouches/constants/index.ts b/src/ts/@overflow/commons/context/pouches/constants/index.ts new file mode 100644 index 0000000..6d84a49 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/constants/index.ts @@ -0,0 +1,2 @@ +export * from './reflect'; +export * from './types'; diff --git a/src/ts/@overflow/commons/context/pouches/constants/reflect.ts b/src/ts/@overflow/commons/context/pouches/constants/reflect.ts new file mode 100644 index 0000000..4bf09bc --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/constants/reflect.ts @@ -0,0 +1,5 @@ +// used to store types to be injected +export const POUCH_DEFINITION = 'loafer:pouch:definition'; + +// used to store types to be injected +export const POUCH_INJECT_DEFINITION = 'loafer:pouch:inject_definition'; diff --git a/src/ts/@overflow/commons/context/pouches/constants/types.ts b/src/ts/@overflow/commons/context/pouches/constants/types.ts new file mode 100644 index 0000000..e43e154 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/constants/types.ts @@ -0,0 +1,7 @@ +export const POUCH_DEFAULT_QUALIFIER = Symbol('__QUALIFIER__'); + +export enum PouchScope { + SINGLETON, + PROTOTYPE, +} + diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts b/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts index 4aa0bc2..954cd93 100644 --- a/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts +++ b/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts @@ -2,72 +2,20 @@ import * as METADATA from '../constants'; import { POUCH_DEFAULT_QUALIFIER } from '../constants'; import InjectConfig from './InjectConfig'; import PouchInjectDefinition from '../config/PouchInjectDefinition'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; +import { getPouchInjectDefinition } from '../util/metadata'; -const Inject = (injectConfig: InjectConfig = {}) => { - return (...args: any[]) => { - let params = []; - for (let i = 0; i < args.length; i++) { - if (args[i]) { - params.push(args[i]); - } - } - - switch(params.length) { - case 1: - return injectClass(injectConfig).apply(this, args); - case 2: - return injectProperty(injectConfig).apply(this, args); - case 3: - if(typeof args[2] === 'number') { - return injectParameter(injectConfig).apply(this, args); - } - return injectMethod(injectConfig).apply(this, args); - default: - throw new Error('@Inject decorators are not valid here!'); - } - }; -}; - -const injectClass = (injectConfig: InjectConfig = {}) => { - return (target: TFunction): TFunction | void => { - throw new Error('Cannot apply @Inject decorator on Class.'); - }; -}; - -const injectProperty = (injectConfig: InjectConfig = {}) => { - return (target: Object, propertyKey: string | symbol): void => { - let pouchInjectDefinition: PouchInjectDefinition = getPouchInjectDefinition(target); +const Inject = (injectConfig: InjectConfig = {}) => createDecorator('Inject', { + propertyDecorator: (target: Object, propertyKey: string | symbol): void => { + let pouchInjectDefinition: PouchInjectDefinition = getPouchInjectDefinition(target, true); pouchInjectDefinition.addInject(injectConfig, propertyKey); - }; -}; - -const injectParameter = (injectConfig: InjectConfig = {}) => { - return (target: Object, propertyKey: string | symbol, parameterIndex: number): void => { - let pouchInjectDefinition: PouchInjectDefinition = getPouchInjectDefinition(target); + }, + parameterDecorator: (target: Object, propertyKey: string | symbol, parameterIndex: number): void => { + let pouchInjectDefinition: PouchInjectDefinition = getPouchInjectDefinition(target, true); pouchInjectDefinition.addInject(injectConfig, propertyKey, parameterIndex); - }; -}; + }, -const injectMethod = (injectConfig: InjectConfig = {}) => { - return (target: Object, propertyKey: string | symbol, - descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void => { - throw new Error('Cannot apply @Inject decorator on Class.'); +}); - // return descriptor; - }; -}; - - - -const getPouchInjectDefinition = (target: Object) => { - let pouchInjectDefinition: PouchInjectDefinition; - if (Reflect.hasOwnMetadata(METADATA.POUCH_INJECT_DEFINITION, target) !== true) { - pouchInjectDefinition = new PouchInjectDefinition(target); - Reflect.defineMetadata(METADATA.POUCH_INJECT_DEFINITION, pouchInjectDefinition, target); - } else { - pouchInjectDefinition = Reflect.getMetadata(METADATA.POUCH_INJECT_DEFINITION, target); - } - return pouchInjectDefinition; -}; export default Inject; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts b/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts index 19b213b..5ecf3c8 100644 --- a/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts +++ b/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts @@ -1,67 +1,21 @@ import * as METADATA from '../constants'; import PouchDefinition from '../config/PouchDefinition'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; +import { getPouchDefinition } from '../util/metadata'; - -const Injectable = (...args: any[]) => { - let params = []; - for (let i = 0; i < args.length; i++) { - if (args[i]) { - params.push(args[i]); +const Injectable = createDecorator('Injectable', { + classDecorator: (target: TFunction): TFunction | void => { + let pouchDefinition: PouchDefinition = getPouchDefinition(target, false); + if (undefined !== pouchDefinition) { + throw new Error('Cannot apply @injectable decorator multiple times.'); } - } - switch(params.length) { - case 1: - return injectableClass.apply(this, args); - case 2: - return injectableProperty.apply(this, args); - case 3: - if(typeof args[2] === 'number') { - return injectableParameter.apply(this, args); - } - return injectableMethod.apply(this, args); - default: - throw new Error('@Injectable decorators are not valid here!'); - } -}; + pouchDefinition = getPouchDefinition(target.prototype, true); + return target; + }, -const injectableClass = (target: TFunction): TFunction | void => { - if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) === true) { - throw new Error('Cannot apply @injectable decorator multiple times.'); - } - - let pouchDefinition: PouchDefinition = getPouchDefinition(target.prototype); - - return target; -}; - - -const injectableProperty = (target: Object, propertyKey: string | symbol): void => { - throw new Error('Cannot apply @Injectable decorator on property.'); -}; - - -const injectableParameter = (target: Object, propertyKey: string | symbol, parameterIndex: number): void => { - throw new Error('Cannot apply @Injectable decorator on parameter.'); -}; - -const injectableMethod = (target: Object, propertyKey: string | symbol, - descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void => { - throw new Error('Cannot apply @Injectable decorator on method.'); - // return descriptor; -}; - -const getPouchDefinition = (target: TFunction) => { - let pouchDefinition: PouchDefinition; - if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { - pouchDefinition = new PouchDefinition(target); - Reflect.defineMetadata(METADATA.POUCH_DEFINITION, pouchDefinition, target); - } else { - pouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); - } - return pouchDefinition; -}; +}); export default Injectable; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts b/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts index 9e1ad01..89b406c 100644 --- a/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts +++ b/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts @@ -1,14 +1,17 @@ import * as METADATA from '../constants'; import PouchDefinition from '../config/PouchDefinition'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; +import { getPouchDefinition } from '../util/metadata'; -const PostConstruct = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { - if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { - throw new Error('Cannot apply @PostConstruct decorator on the not @Injectable class.'); - } - let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); - pouchDefinition.addPostConstruct(propertyKey); - - return descriptor; -}; +const PostConstruct = createDecorator('PostConstruct', { + methodDecorator: (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { + let pouchDefinition = getPouchDefinition(target, false); + if (undefined === pouchDefinition) { + throw new Error('Cannot apply @PostConstruct decorator on the not @Injectable class.'); + } + pouchDefinition.addPostConstruct(propertyKey); + return descriptor; + }, +}); export default PostConstruct; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts b/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts index 3434db0..a1c5e0c 100644 --- a/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts +++ b/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts @@ -1,14 +1,17 @@ import * as METADATA from '../constants'; import PouchDefinition from '../config/PouchDefinition'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; +import { getPouchDefinition } from '../util/metadata'; -const PreDestroy = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { - if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { - throw new Error('Cannot apply @PreDestroy decorator on the not @Injectable class.'); - } - let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); - pouchDefinition.addPreDestroy(propertyKey); - - return descriptor; -}; +const PreDestroy = createDecorator('PreDestroy', { + methodDecorator: (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { + let pouchDefinition = getPouchDefinition(target, false); + if (undefined === pouchDefinition) { + throw new Error('Cannot apply @PreDestroy decorator on the not @Injectable class.'); + } + pouchDefinition.addPreDestroy(propertyKey); + return descriptor; + }, +}); export default PreDestroy; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts b/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts index 89c02f9..819fc56 100644 --- a/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts +++ b/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts @@ -1,16 +1,21 @@ import * as METADATA from '../constants'; import PouchDefinition from '../config/PouchDefinition'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; +import { getPouchDefinition } from '../util/metadata'; -const Qualifier = (value: string | symbol) => { - return (target: TFunction): TFunction | void => { - if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { +const Qualifier = (value: string | symbol) => createDecorator('Qualifier', { + classDecorator: (target: TFunction): TFunction | void => { + let pouchDefinition = getPouchDefinition(target, false); + if (undefined === pouchDefinition) { throw new Error('Cannot apply @Qualifier decorator on the not @Injectable class.'); } - let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); - pouchDefinition.qualifier = value; + if (undefined !== pouchDefinition.qualifier) { + throw new Error('Cannot apply @Qualifier decorator multiple times.'); + } + pouchDefinition.qualifier = value; return target; - }; -}; + }, +}); export default Qualifier; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts b/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts index 48819ee..7660731 100644 --- a/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts +++ b/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts @@ -1,17 +1,18 @@ import * as METADATA from '../constants'; import PouchDefinition from '../config/PouchDefinition'; import { PouchScope } from '../constants'; +import createDecorator from '@overflow/commons/util/decorators/createDecorator'; +import { getPouchDefinition } from '../util/metadata'; -const Scope = (value: PouchScope = PouchScope.SINGLETON) => { - return (target: TFunction): TFunction | void => { - if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { +const Scope = (value: PouchScope = PouchScope.SINGLETON) => createDecorator('Scope', { + classDecorator: (target: TFunction): TFunction | void => { + let pouchDefinition = getPouchDefinition(target, false); + if (undefined === pouchDefinition) { throw new Error('Cannot apply @Scope decorator on the not @Injectable class.'); } - let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); pouchDefinition.scope = value; - return target; - }; -}; + }, +}); export default Scope; diff --git a/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts b/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts index aaeda7f..5749634 100644 --- a/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts +++ b/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts @@ -1,8 +1,6 @@ import * as METADATA from '../constants'; import { - ClassConstructor, - DecoratorType, PouchScope, POUCH_DEFAULT_QUALIFIER, } from '../constants'; @@ -27,7 +25,7 @@ class PouchFactory { /** * getPouch */ - public getPouch(type: ClassConstructor, ...args: any[]): T { + public getPouch(type: Newable, ...args: any[]): T { let qualifier = POUCH_DEFAULT_QUALIFIER; return this.getPouchByQualifier(type, qualifier, args); } @@ -35,7 +33,7 @@ class PouchFactory { /** * getPouchByQualifier */ - public getPouchByQualifier(type: ClassConstructor, qualifier: string | symbol, ...args: any[]): T { + public getPouchByQualifier(type: Newable, qualifier: string | symbol, ...args: any[]): T { let clazz: Function = type.prototype; let instance = this._getPouch(clazz, qualifier, args); @@ -55,7 +53,7 @@ class PouchFactory { /** * registerPouch */ - public registerPouchDefinition(type: ClassConstructor, pouchDefinition: PouchDefinition): void { + public registerPouchDefinition(type: Newable, pouchDefinition: PouchDefinition): void { let clazz: Function = type.prototype; if (this.pouchDefinitionMap.has(clazz)) { throw new Error(`Pouch Definition of [${clazz.name}] is already exist.`); diff --git a/src/ts/@overflow/commons/context/pouches/util/metadata/index.ts b/src/ts/@overflow/commons/context/pouches/util/metadata/index.ts new file mode 100644 index 0000000..f5e629b --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/util/metadata/index.ts @@ -0,0 +1,2 @@ +export * from './inject'; +export * from './pouch'; diff --git a/src/ts/@overflow/commons/context/pouches/util/metadata/inject.ts b/src/ts/@overflow/commons/context/pouches/util/metadata/inject.ts new file mode 100644 index 0000000..1dc8dc4 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/util/metadata/inject.ts @@ -0,0 +1,8 @@ +import getClassMetadata from '@overflow/commons/util/metadata/getClassMetadata'; + +import * as METADATA from '../../constants'; +import PouchInjectDefinition from '../../config/PouchInjectDefinition'; + +export const getPouchInjectDefinition = + (target: TFunction | Object, isCreate: boolean = false) => + getClassMetadata(target, METADATA.POUCH_INJECT_DEFINITION, PouchInjectDefinition, isCreate); diff --git a/src/ts/@overflow/commons/context/pouches/util/metadata/pouch.ts b/src/ts/@overflow/commons/context/pouches/util/metadata/pouch.ts new file mode 100644 index 0000000..5d66a71 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/util/metadata/pouch.ts @@ -0,0 +1,8 @@ +import getClassMetadata from '@overflow/commons/util/metadata/getClassMetadata'; + +import * as METADATA from '../../constants'; +import PouchDefinition from '../../config/PouchDefinition'; + +export const getPouchDefinition = + (target: TFunction | Object, isCreate: boolean = false) => + getClassMetadata(target, METADATA.POUCH_DEFINITION, PouchDefinition, isCreate); diff --git a/src/ts/@overflow/commons/context/util/metadata/configuration.ts b/src/ts/@overflow/commons/context/util/metadata/configuration.ts new file mode 100644 index 0000000..ee693ec --- /dev/null +++ b/src/ts/@overflow/commons/context/util/metadata/configuration.ts @@ -0,0 +1,9 @@ +import getClassMetadata from '@overflow/commons/util/metadata/getClassMetadata'; + +import * as METADATA from '../../constants'; +import ConfigurationDefinition from '../../config/ConfigurationDefinition'; + +export const getConfigurationDefinition = + (target: TFunction | Object, isCreate: boolean = false) => + getClassMetadata(target, METADATA.CONTEXT_CONFIGURATION_DEFINITION, ConfigurationDefinition, isCreate); + diff --git a/src/ts/@overflow/commons/context/util/metadata/index.ts b/src/ts/@overflow/commons/context/util/metadata/index.ts new file mode 100644 index 0000000..75a1114 --- /dev/null +++ b/src/ts/@overflow/commons/context/util/metadata/index.ts @@ -0,0 +1 @@ +export * from './configuration'; diff --git a/src/ts/@overflow/commons/core/constants/index.ts b/src/ts/@overflow/commons/core/constants/index.ts new file mode 100644 index 0000000..1cd2e39 --- /dev/null +++ b/src/ts/@overflow/commons/core/constants/index.ts @@ -0,0 +1,2 @@ +export * from './types'; +export * from './reflect'; diff --git a/src/ts/@overflow/commons/core/constants/reflect.ts b/src/ts/@overflow/commons/core/constants/reflect.ts new file mode 100644 index 0000000..7898d00 --- /dev/null +++ b/src/ts/@overflow/commons/core/constants/reflect.ts @@ -0,0 +1,6 @@ +// used to access design time types +export const DESIGN_TYPE = 'design:type'; +// used to access design time parameter types +export const DESIGN_PARAMTYPES = 'design:paramtypes'; +// used to access design time return type +export const DESIGN_RETURNTYPE = 'design:returntype'; diff --git a/src/ts/@overflow/commons/core/constants/types.ts b/src/ts/@overflow/commons/core/constants/types.ts new file mode 100644 index 0000000..dde5a51 --- /dev/null +++ b/src/ts/@overflow/commons/core/constants/types.ts @@ -0,0 +1,8 @@ +export type Newable = {new(...args: any[]): T}; + +export enum DecoratorType { + CLASS, + PROPERTY, + PARAMETER, + METHOD, +} diff --git a/src/ts/@overflow/commons/utils/TargetCreate.tsx b/src/ts/@overflow/commons/util/TargetCreate.tsx similarity index 80% rename from src/ts/@overflow/commons/utils/TargetCreate.tsx rename to src/ts/@overflow/commons/util/TargetCreate.tsx index db82ba8..897ad00 100644 --- a/src/ts/@overflow/commons/utils/TargetCreate.tsx +++ b/src/ts/@overflow/commons/util/TargetCreate.tsx @@ -25,11 +25,11 @@ export class TargetCreator { let obj: any; obj = { - "ip": ip, - "port": port, - "portType": portType, + 'ip': ip, + 'port': port, + 'portType': portType, // "targetType":"", - "vendorName": vendorName, + 'vendorName': vendorName, // "kinds":"", // "version":"", }; @@ -38,8 +38,8 @@ export class TargetCreator { } - public toString() :string { + public toString():string { return JSON.stringify(this.list); } -} \ No newline at end of file +} diff --git a/src/ts/@overflow/commons/utils/Utils.tsx b/src/ts/@overflow/commons/util/Utils.tsx similarity index 100% rename from src/ts/@overflow/commons/utils/Utils.tsx rename to src/ts/@overflow/commons/util/Utils.tsx diff --git a/src/ts/@overflow/commons/util/decorators/createDecorator.ts b/src/ts/@overflow/commons/util/decorators/createDecorator.ts new file mode 100644 index 0000000..3d9c098 --- /dev/null +++ b/src/ts/@overflow/commons/util/decorators/createDecorator.ts @@ -0,0 +1,46 @@ +export interface DecoratorFactory { + classDecorator?: ClassDecorator; + propertyDecorator?: PropertyDecorator; + parameterDecorator?: ParameterDecorator; + methodDecorator?: MethodDecorator; +} + +const createDecorator = (name: string, decoratorFactory: DecoratorFactory) => { + return (...args: any[]) => { + let params = []; + for (let i = 0; i < args.length; i++) { + if (args[i]) { + params.push(args[i]); + } + } + + switch(params.length) { + case 1: + if (undefined !== decoratorFactory.classDecorator) { + return decoratorFactory.classDecorator.apply(this, args); + } + throw new Error(`Cannot apply @${name} decorator on Class.`); + case 2: + case 1: + if (undefined !== decoratorFactory.propertyDecorator) { + return decoratorFactory.propertyDecorator.apply(this, args); + } + throw new Error(`Cannot apply @${name} decorator on Property.`); + case 3: + if(typeof args[2] === 'number') { + if (undefined !== decoratorFactory.parameterDecorator) { + return decoratorFactory.parameterDecorator.apply(this, args); + } + throw new Error(`Cannot apply @${name} decorator on Parameter.`); + } + if (undefined !== decoratorFactory.methodDecorator) { + return decoratorFactory.methodDecorator.apply(this, args); + } + throw new Error(`Cannot apply @${name} decorator on Method.`); + default: + throw new Error(`@${name} decorators are not valid here!`); + } + }; +}; + +export default createDecorator; diff --git a/src/ts/@overflow/commons/util/metadata/getClassMetadata.ts b/src/ts/@overflow/commons/util/metadata/getClassMetadata.ts new file mode 100644 index 0000000..a26d8ac --- /dev/null +++ b/src/ts/@overflow/commons/util/metadata/getClassMetadata.ts @@ -0,0 +1,24 @@ +export type MetadataDefinable = {new(target: Function): T}; + +const getClassMetadata = (target: TFunction | Object, + metadataKey: any, + definitionType: MetadataDefinable, + isCreate: boolean = false): DefinitionType => { + + let clazz = target instanceof Function ? target.prototype : target; + let definition: DefinitionType; + if (Reflect.hasOwnMetadata(metadataKey, clazz) !== true) { + if (!isCreate) { + return undefined; + } + definition = Object.create(definitionType.prototype); + definition.constructor.call(definition, clazz); + + Reflect.defineMetadata(metadataKey, definition, clazz); + } else { + definition = Reflect.getMetadata(metadataKey, clazz); + } + return definition; +}; + +export default getClassMetadata; diff --git a/src/ts/@overflow/commons/utils/Rest.tsx b/src/ts/@overflow/commons/utils/Rest.tsx deleted file mode 100644 index 58b8f01..0000000 --- a/src/ts/@overflow/commons/utils/Rest.tsx +++ /dev/null @@ -1,54 +0,0 @@ - - -const url = "http://192.168.1.209:8080/v1/overflow/services"; - -export class OFRest { - - obj: any; - - - constructor(serviceName: string, methodName: string, data: any) { - - this.obj = { - "serviceName": serviceName, - "methodName": methodName, - "param": { - "model": JSON.stringify(data) - } - - }; - } - - public Call() { - - return fetch(url, { - method: 'POST', - headers: { - 'Accept': 'application/json', - }, - body: JSON.stringify(this.obj) - }); - } - - public CallWithCB(callback: Function) { - fetch(url, { - method: 'POST', - headers: { - 'Accept': 'application/json', - }, - body: JSON.stringify(this.obj) - }).then(function (res) { - return res.json(); - }).then(function (json) { - if (json.error != undefined) { - console.log(json.error); - return; - } - callback(json); - }).catch(function (err) { - console.log(err); - }); - } - -} - diff --git a/src/ts/@overflow/discovery/react/components/DiscoveryTable.tsx b/src/ts/@overflow/discovery/react/components/DiscoveryTable.tsx index 12d80d3..d359618 100644 --- a/src/ts/@overflow/discovery/react/components/DiscoveryTable.tsx +++ b/src/ts/@overflow/discovery/react/components/DiscoveryTable.tsx @@ -54,7 +54,7 @@ export class DiscoveryTable extends React.Component { { key: 'telnet', text: 'Telnet', value: 'telnet' }, { key: 'casandra', text: 'Casandra', value: 'casandra' }, { key: 'mongodb', text: 'mongoDB', value: 'mongodb' }, - { key: 'rmi', text: 'RMI', value: 'rmi' } + { key: 'rmi', text: 'RMI', value: 'rmi' }, ]; } diff --git a/src/ts/@overflow/infra/react/components/InfraDetail.tsx b/src/ts/@overflow/infra/react/components/InfraDetail.tsx index 372e7cd..8c81f79 100644 --- a/src/ts/@overflow/infra/react/components/InfraDetail.tsx +++ b/src/ts/@overflow/infra/react/components/InfraDetail.tsx @@ -10,7 +10,7 @@ import InfraHost from '@overflow/infra/api/model/InfraHost'; import InfraMachine from '@overflow/infra/api/model/InfraMachine'; import InfraOS from '@overflow/infra/api/model/InfraOS'; -import * as Utils from '@overflow/commons/utils/Utils'; +import * as Utils from '@overflow/commons/util/Utils'; export interface StateProps { target?: Target; diff --git a/types/react-router-redux/index.d.ts b/types/react-router-redux/index.d.ts deleted file mode 100644 index 9a1d779..0000000 --- a/types/react-router-redux/index.d.ts +++ /dev/null @@ -1,77 +0,0 @@ -// Type definitions for react-router-redux 5.0 -// Project: https://github.com/ReactTraining/react-router/tree/master/packages/react-router-redux -// Definitions by: Huy Nguyen -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 -import { - Store, - Dispatch, - Action, - Middleware -} from 'redux'; -import { - History, - Location, - Path, - LocationState, - LocationDescriptor -} from 'history'; -import * as React from 'react'; - -export interface ConnectedRouterProps { - store?: Store; - history?: History; -} -export class ConnectedRouter extends React.Component> {} - -export const LOCATION_CHANGE: string; - -export interface RouterState { - location: Location | null; -} - -export function routerReducer(state?: RouterState, action?: RouterAction): RouterState; - -export const CALL_HISTORY_METHOD: string; - -export function push(location: LocationDescriptor, state?: LocationState): RouterAction; -export function replace(location: LocationDescriptor, state?: LocationState): RouterAction; -export function go(n: number): RouterAction; -export function goBack(): RouterAction; -export function goForward(): RouterAction; - -export const routerActions: { - push: typeof push - replace: typeof replace - go: typeof go - goBack: typeof goBack - goForward: typeof goForward -}; - -export interface LocationActionPayload { - method: string; - args?: any[]; -} - -export interface RouterAction extends Action { - type: typeof CALL_HISTORY_METHOD; - payload: LocationActionPayload; -} - -export interface LocationChangeAction extends Action { - type: typeof LOCATION_CHANGE; - payload: Location & { - props?: { - match: { - path: string; - url: string; - params: any; - isExact: boolean; - }, - location: Location; - history: History; - } - }; -} - -export function routerMiddleware(history: History): Middleware; \ No newline at end of file