koatty_container
Advanced tools
Comparing version 1.6.11 to 1.6.12
@@ -5,14 +5,6 @@ # Changelog | ||
### [1.6.10](https://github.com/koatty/koatty_container/compare/v1.6.8...v1.6.10) (2021-12-08) | ||
### [1.6.12](https://github.com/koatty/koatty_container/compare/v1.6.12-1...v1.6.12) (2021-12-18) | ||
### [1.6.8](https://github.com/koatty/koatty_container/compare/v1.6.7...v1.6.8) (2021-11-23) | ||
### [1.6.12-1](https://github.com/koatty/koatty_container/compare/v1.6.12-0...v1.6.12-1) (2021-12-18) | ||
### [1.5.2](https://github.com/koatty/koatty_container/compare/v1.4.4...v1.5.2) (2021-07-09) | ||
### [1.4.4](https://github.com/koatty/koatty_container/compare/v1.4.3...v1.4.4) (2021-07-07) | ||
### [1.4.3](https://github.com/koatty/koatty_container/compare/v1.4.2...v1.4.3) (2021-06-29) | ||
### [1.4.2](https://github.com/koatty/koatty_container/compare/v1.4.1...v1.4.2) (2021-06-29) | ||
### [1.4.1](https://github.com/koatty/koatty_container/compare/v1.3.12...v1.4.1) (2021-06-28) | ||
### [1.6.12-0](https://github.com/koatty/koatty_container/compare/v1.6.10...v1.6.12-0) (2021-12-17) |
@@ -0,12 +1,473 @@ | ||
/*! | ||
* @Author: richen | ||
* @Date: 2021-12-18 12:13:33 | ||
* @License: BSD (3-Clause) | ||
* @Copyright (c) - <richenlin(at)gmail.com> | ||
* @HomePage: https://koatty.org/ | ||
*/ | ||
/** | ||
* Executed after specifying the PointCut method. | ||
* | ||
* @export | ||
* @param {(string | Function)} aopName | ||
* @returns {MethodDecorator} | ||
*/ | ||
export declare function After(aopName: string | Function): MethodDecorator; | ||
/** | ||
* Executed after execution of each method of the specified PointCut class. | ||
* | ||
* @export | ||
* @param {string} aopName | ||
* @returns {Function} | ||
*/ | ||
export declare function AfterEach(aopName?: string | Function): ClassDecorator; | ||
/** | ||
* defined AOP type | ||
* | ||
* @export | ||
* @enum {number} | ||
*/ | ||
export declare enum AOPType { | ||
"Before" = "Before", | ||
"BeforeEach" = "BeforeEach", | ||
"After" = "After", | ||
"AfterEach" = "AfterEach" | ||
} | ||
/** | ||
* Base Application | ||
* | ||
* @export | ||
* @interface Application | ||
*/ | ||
export declare interface Application { | ||
env: string; | ||
options: any; | ||
use: (fn: Function) => any; | ||
config: (name: string, type?: string) => any; | ||
on(event: string, callback: () => void): any; | ||
once(event: string, callback: () => void): any; | ||
/** | ||
* app metadata | ||
* | ||
* @memberof Application | ||
*/ | ||
getMetaData: (key: string) => unknown; | ||
setMetaData: (key: string, value: unknown) => Map<string, unknown>; | ||
} | ||
/** | ||
* Indicates that an decorated class is a "aspect". | ||
* | ||
* @export | ||
* @param {string} [identifier] | ||
* @returns {ClassDecorator} | ||
*/ | ||
export declare function Aspect(identifier?: string): ClassDecorator; | ||
/** | ||
* Marks a constructor method as to be autowired by Koatty"s dependency injection facilities. | ||
* | ||
* @export | ||
* @param {string} [identifier] | ||
* @param {ComponentType} [type] | ||
* @param {any[]} [constructArgs] | ||
* @param {boolean} [isDelay=false] | ||
* @returns {PropertyDecorator} | ||
*/ | ||
export declare function Autowired(identifier?: string, type?: ComponentType, constructArgs?: any[], isDelay?: boolean): PropertyDecorator; | ||
/** | ||
* Executed before specifying the PointCut method. | ||
* | ||
* @export | ||
* @param {(string | Function)} aopName | ||
* @returns {MethodDecorator} | ||
*/ | ||
export declare function Before(aopName: string | Function): MethodDecorator; | ||
/** | ||
* Executed after execution of each method of the specified PointCut class. | ||
* | ||
* @export | ||
* @param {string} [aopName] | ||
* @returns {Function} | ||
*/ | ||
export declare function BeforeEach(aopName?: string | Function): ClassDecorator; | ||
export declare type ComponentType = 'COMPONENT' | 'CONTROLLER' | 'MIDDLEWARE' | 'SERVICE'; | ||
/** | ||
* Indicates that an decorated configuration as a property. | ||
* | ||
* @export | ||
* @param {string} identifier configuration key | ||
* @param {string} [type] configuration type | ||
* @returns {PropertyDecorator} | ||
*/ | ||
export declare const Config: typeof Value; | ||
/** | ||
* IOC Container | ||
* | ||
* @export | ||
* @class Container | ||
* @implements {IContainer} | ||
*/ | ||
export declare class Container implements IContainer { | ||
/** | ||
* | ||
* | ||
* @static | ||
* @returns | ||
* @memberof ValidateUtil | ||
*/ | ||
static getInstance(): Container; | ||
/** | ||
* creates an instance of Container. | ||
* @param {*} app | ||
* @memberof Container | ||
*/ | ||
/** | ||
* set app | ||
* | ||
* @param {Koatty} app | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
setApp(app: Application): void; | ||
/** | ||
* get app | ||
* | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getApp(): Application; | ||
/** | ||
* registering an instance of a class to an IOC container. | ||
* | ||
* @template T | ||
* @param {T} target | ||
* @param {ObjectDefinitionOptions} [options] | ||
* @returns {T} | ||
* @memberof Container | ||
*/ | ||
reg<T>(target: T, options?: ObjectDefinitionOptions): T; | ||
reg<T>(identifier: string, target: T, options?: ObjectDefinitionOptions): T; | ||
/** | ||
* get instance from IOC container. | ||
* | ||
* @param {string} identifier | ||
* @param {ComponentType} [type="SERVICE"] | ||
* @param {any[]} [args=[]] | ||
* @returns {*} | ||
* @memberof Container | ||
*/ | ||
get(identifier: string, type?: ComponentType, args?: any[]): any; | ||
/** | ||
* get class from IOC container by identifier. | ||
* | ||
* @param {string} identifier | ||
* @param {ComponentType} [type="SERVICE"] | ||
* @returns {Function} | ||
* @memberof Container | ||
*/ | ||
getClass(identifier: string, type?: ComponentType): Function; | ||
/** | ||
* get instance from IOC container by class. | ||
* | ||
* @template T | ||
* @param {T} target | ||
* @param {any[]} [args=[]] | ||
* @returns {T} | ||
* @memberof Container | ||
*/ | ||
getInsByClass<T>(target: T, args?: any[]): T; | ||
/** | ||
* get metadata from class | ||
* | ||
* @static | ||
* @param {(string | symbol)} metadataKey | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} [propertyKey] | ||
* @returns | ||
* @memberof Injectable | ||
*/ | ||
getMetadataMap(metadataKey: string | symbol, target: Function | Object, propertyKey?: string | symbol): any; | ||
/** | ||
* get identifier from class | ||
* | ||
* @param {Function | Object} target | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getIdentifier(target: Function | Object): string; | ||
/** | ||
* get component type from class | ||
* | ||
* @param {Function} target | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getType(target: Function | Object): any; | ||
/** | ||
* save class to Container | ||
* | ||
* @param {ComponentType} type | ||
* @param {Function} module | ||
* @param {string} identifier | ||
* @memberof Container | ||
*/ | ||
saveClass(type: ComponentType, module: Function, identifier: string): void; | ||
/** | ||
* get all class from Container | ||
* | ||
* @param {ComponentType} type | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
listClass(type: ComponentType): any[]; | ||
/** | ||
* save meta data to class or property | ||
* | ||
* @param {string} type | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {string} [propertyName] | ||
* @memberof Container | ||
*/ | ||
saveClassMetadata(type: string, decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName?: string): void; | ||
/** | ||
* attach data to class or property | ||
* | ||
* @param {string} type | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {string} [propertyName] | ||
* @memberof Container | ||
*/ | ||
attachClassMetadata(type: string, decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName?: string): void; | ||
/** | ||
* get single data from class or property | ||
* | ||
* @param {string} type | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {(Function | object)} target | ||
* @param {string} [propertyName] | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getClassMetadata(type: string, decoratorNameKey: string | symbol, target: Function | Object, propertyName?: string): any; | ||
/** | ||
* save property data to class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} propertyName | ||
* @memberof Container | ||
*/ | ||
savePropertyData(decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName: string | symbol): void; | ||
/** | ||
* attach property data to class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} propertyName | ||
* @memberof Container | ||
*/ | ||
attachPropertyData(decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName: string | symbol): void; | ||
/** | ||
* get property data from class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} propertyName | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getPropertyData(decoratorNameKey: string | symbol, target: Function | Object, propertyName: string | symbol): any; | ||
/** | ||
* list property data from class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {(Function | object)} target | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
listPropertyData(decoratorNameKey: string | symbol, target: Function | Object): any; | ||
} | ||
/** | ||
* Base Context. | ||
* | ||
* @export | ||
* @interface Context | ||
* @extends {Koa.Context} | ||
*/ | ||
export declare interface Context { | ||
/** | ||
* Replace ctx.throw | ||
* | ||
* @type {(status: number, message?: string)} | ||
* @type {(message: string, code?: number, status?: HttpStatusCode)} | ||
* @memberof Context | ||
*/ | ||
throw(status: number, message?: string): never; | ||
throw(message: string, code?: number, status?: any): never; | ||
/** | ||
* context metadata | ||
* | ||
* @memberof Context | ||
*/ | ||
getMetaData: (key: string) => unknown; | ||
setMetaData: (key: string, value: unknown) => Map<string, unknown>; | ||
} | ||
/** | ||
* Find all methods on a given ES6 class | ||
* | ||
* @param {*} target | ||
* @param {boolean} isSelfProperties | ||
* @returns {string[]} | ||
*/ | ||
export declare function getMethodNames(target: any, isSelfProperties?: boolean): string[]; | ||
/** | ||
* Find all property on a given ES6 class | ||
* | ||
* @export | ||
* @param {*} target | ||
* @param {boolean} isSelfProperties | ||
* @returns {string[]} | ||
*/ | ||
export declare function getPropertyNames(target: any, isSelfProperties?: boolean): string[]; | ||
/** | ||
* Aspect interface | ||
* | ||
* @export | ||
* @interface IAspect | ||
*/ | ||
export declare interface IAspect { | ||
app: any; | ||
run: (...args: any[]) => Promise<any>; | ||
} | ||
/** | ||
* Container interface | ||
* | ||
* @export | ||
* @interface IContainer | ||
*/ | ||
export declare interface IContainer { | ||
setApp(app: Application): void; | ||
reg<T>(target: T, options?: ObjectDefinitionOptions): T; | ||
reg<T>(identifier: string, target: T, options?: ObjectDefinitionOptions): T; | ||
get(identifier: string, type?: ComponentType, args?: any[]): any; | ||
getClass(identifier: string, type?: ComponentType): Function; | ||
getInsByClass<T>(target: T, args?: any[]): T; | ||
saveClass(type: ComponentType, module: Function, identifier: string): void; | ||
listClass(type: ComponentType): any[]; | ||
getIdentifier(target: Function): string; | ||
getType(target: Function): string; | ||
getMetadataMap(metadataKey: string | symbol, target: any, propertyKey?: string | symbol): any; | ||
saveClassMetadata(type: string, decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName?: string): void; | ||
attachClassMetadata(type: string, decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName?: string): void; | ||
getClassMetadata(type: string, decoratorNameKey: string | symbol, target: Function | Object, propertyName?: string): any; | ||
savePropertyData(decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName: string | symbol): void; | ||
attachPropertyData(decoratorNameKey: string | symbol, data: any, target: Function | Object, propertyName: string | symbol): void; | ||
getPropertyData(decoratorNameKey: string | symbol, target: Function | Object, propertyName: string | symbol): any; | ||
listPropertyData(decoratorNameKey: string | symbol, target: Function | Object): any[]; | ||
} | ||
export declare const IOCContainer: Container; | ||
/** | ||
* BeanFactory Object interface | ||
* | ||
* @export | ||
* @interface ObjectDefinitionOptions | ||
*/ | ||
export declare interface ObjectDefinitionOptions { | ||
isAsync?: boolean; | ||
initMethod?: string; | ||
destroyMethod?: string; | ||
scope?: Scope; | ||
type: ComponentType; | ||
args: any[]; | ||
} | ||
/** | ||
* get metadata value of a metadata key on the prototype chain of an object and property | ||
* @param metadataKey metadata key | ||
* @param target the target of metadataKey | ||
*/ | ||
export declare function RecursiveGetMetadata(metadataKey: any, target: any, propertyKey?: string | symbol): any[]; | ||
/** | ||
* | ||
* | ||
* @export | ||
* @interface ReflectResult | ||
*/ | ||
export declare interface ReflectResult { | ||
[key: string]: TagPropsMetadata[]; | ||
} | ||
/** | ||
* @ author: richen | ||
* @ copyright: Copyright (c) - <richenlin(at)gmail.com> | ||
* @ license: MIT | ||
* @ version: 2020-05-10 11:31:10 | ||
* @ version: 2020-05-10 11:41:01 | ||
*/ | ||
export * from "./Container"; | ||
export * from "./IContainer"; | ||
export * from "./Util"; | ||
export { Autowired } from "./Autowired"; | ||
export { Config, Value } from "./Value"; | ||
export { AOPType, IAspect, Aspect, Before, BeforeEach, After, AfterEach } from "./AOP"; | ||
export declare type Scope = 'Singleton' | 'Prototype'; | ||
/** | ||
* | ||
* | ||
* @export | ||
* @interface TagClsMetadata | ||
*/ | ||
export declare interface TagClsMetadata { | ||
id: string; | ||
originName: string; | ||
} | ||
export declare const TAGGED_AOP = "TAGGED_AOP"; | ||
export declare const TAGGED_ARGS = "TAGGED_ARGS"; | ||
export declare const TAGGED_CLS = "INJECT_TAGGED_CLS"; | ||
export declare const TAGGED_METHOD = "INJECT_TAGGED_METHOD"; | ||
export declare const TAGGED_PROP = "INJECT_TAGGED_PROP"; | ||
/** | ||
* | ||
* | ||
* @export | ||
* @interface TagPropsMetadata | ||
*/ | ||
export declare interface TagPropsMetadata { | ||
key: string | number | symbol; | ||
value: any; | ||
} | ||
/** | ||
* Indicates that an decorated configuration as a property. | ||
* | ||
* @export | ||
* @param {string} identifier configuration key | ||
* @param {string} [type] configuration type | ||
* @returns {PropertyDecorator} | ||
*/ | ||
export declare function Value(key?: string, type?: string): PropertyDecorator; | ||
export { } |
1100
dist/index.js
@@ -1,26 +0,1084 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AfterEach = exports.After = exports.BeforeEach = exports.Before = exports.Aspect = exports.AOPType = exports.Value = exports.Config = exports.Autowired = void 0; | ||
const tslib_1 = require("tslib"); | ||
/*! | ||
* @Author: richen | ||
* @Date: 2021-12-18 12:13:22 | ||
* @License: BSD (3-Clause) | ||
* @Copyright (c) - <richenlin(at)gmail.com> | ||
* @HomePage: https://koatty.org/ | ||
*/ | ||
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
require('reflect-metadata'); | ||
var helper = require('koatty_lib'); | ||
function _interopNamespace(e) { | ||
if (e && e.__esModule) return e; | ||
var n = Object.create(null); | ||
if (e) { | ||
Object.keys(e).forEach(function (k) { | ||
if (k !== 'default') { | ||
var d = Object.getOwnPropertyDescriptor(e, k); | ||
Object.defineProperty(n, k, d.get ? d : { | ||
enumerable: true, | ||
get: function () { return e[k]; } | ||
}); | ||
} | ||
}); | ||
} | ||
n["default"] = e; | ||
return Object.freeze(n); | ||
} | ||
var helper__namespace = /*#__PURE__*/_interopNamespace(helper); | ||
// used to store class properties aop | ||
const TAGGED_AOP = 'TAGGED_AOP'; | ||
// used to store class properties args | ||
const TAGGED_ARGS = 'TAGGED_ARGS'; | ||
// used to store class to be injected | ||
const TAGGED_CLS = 'INJECT_TAGGED_CLS'; | ||
// used to store class properties tags | ||
const TAGGED_PROP = 'INJECT_TAGGED_PROP'; | ||
// used to store class method to be injected | ||
const TAGGED_METHOD = 'INJECT_TAGGED_METHOD'; | ||
/* | ||
* @Author: richen | ||
* @Date: 2020-12-17 20:04:07 | ||
* @LastEditors: Please set LastEditors | ||
* @LastEditTime: 2021-12-18 02:58:21 | ||
* @License: BSD (3-Clause) | ||
* @Copyright (c) - <richenlin(at)gmail.com> | ||
*/ | ||
// get property of an object | ||
const functionPrototype = Object.getPrototypeOf(Function); | ||
// https://tc39.github.io/ecma262/#sec-ordinarygetprototypeof | ||
function ordinaryGetPrototypeOf(obj) { | ||
const proto = Object.getPrototypeOf(obj); | ||
if (typeof obj !== "function" || obj === functionPrototype) { | ||
return proto; | ||
} | ||
// TypeScript doesn't set __proto__ in ES5, as it's non-standard. | ||
// Try to determine the superclass constructor. Compatible implementations | ||
// must either set __proto__ on a subclass constructor to the superclass constructor, | ||
// or ensure each class has a valid `constructor` property on its prototype that | ||
// points back to the constructor. | ||
// If this is not the same as Function.[[Prototype]], then this is definitely inherited. | ||
// This is the case when in ES6 or when using __proto__ in a compatible browser. | ||
if (proto !== functionPrototype) { | ||
return proto; | ||
} | ||
// If the super prototype is Object.prototype, null, or undefined, then we cannot determine the heritage. | ||
const prototype = obj.prototype; | ||
const prototypeProto = prototype && Object.getPrototypeOf(prototype); | ||
// tslint:disable-next-line: triple-equals | ||
if (prototypeProto == undefined || prototypeProto === Object.prototype) { | ||
return proto; | ||
} | ||
// If the constructor was not a function, then we cannot determine the heritage. | ||
const constructor = prototypeProto.constructor; | ||
if (typeof constructor !== "function") { | ||
return proto; | ||
} | ||
// If we have some kind of self-reference, then we cannot determine the heritage. | ||
if (constructor === obj) { | ||
return proto; | ||
} | ||
// we have a pretty good guess at the heritage. | ||
return constructor; | ||
} | ||
/** | ||
* get metadata value of a metadata key on the prototype chain of an object and property | ||
* @param metadataKey metadata key | ||
* @param target the target of metadataKey | ||
*/ | ||
function RecursiveGetMetadata(metadataKey, target, propertyKey) { | ||
var _a; | ||
// get metadata value of a metadata key on the prototype | ||
// let metadata = Reflect.getOwnMetadata(metadataKey, target, propertyKey); | ||
const IOCContainer = Container.getInstance(); | ||
const metadata = (_a = IOCContainer.listPropertyData(metadataKey, target)) !== null && _a !== void 0 ? _a : {}; | ||
// get metadata value of a metadata key on the prototype chain | ||
let parent = ordinaryGetPrototypeOf(target); | ||
while (parent !== null) { | ||
// metadata = Reflect.getOwnMetadata(metadataKey, parent, propertyKey); | ||
const metadata = IOCContainer.listPropertyData(metadataKey, parent); | ||
if (metadata) { | ||
for (const n in metadata) { | ||
if (!metadata.hasOwnProperty(n)) { | ||
metadata[n] = metadata[n]; | ||
} | ||
} | ||
} | ||
parent = ordinaryGetPrototypeOf(parent); | ||
} | ||
return metadata; | ||
} | ||
/** | ||
* Find all methods on a given ES6 class | ||
* | ||
* @param {*} target | ||
* @param {boolean} isSelfProperties | ||
* @returns {string[]} | ||
*/ | ||
function getMethodNames(target, isSelfProperties = false) { | ||
const result = []; | ||
const enumerableOwnKeys = Object.getOwnPropertyNames(target.prototype); | ||
if (!isSelfProperties) { | ||
// searching prototype chain for methods | ||
let parent = ordinaryGetPrototypeOf(target); | ||
while (helper__namespace.isClass(parent) && parent.constructor) { | ||
const allOwnKeysOnPrototype = Object.getOwnPropertyNames(parent.prototype); | ||
// get methods from es6 class | ||
allOwnKeysOnPrototype.forEach((k) => { | ||
if (!result.includes(k) && helper__namespace.isFunction(parent.prototype[k])) { | ||
result.push(k); | ||
} | ||
}); | ||
parent = ordinaryGetPrototypeOf(parent); | ||
} | ||
} | ||
// leave out those methods on Object's prototype | ||
enumerableOwnKeys.forEach((k) => { | ||
if (!result.includes(k) && helper__namespace.isFunction(target.prototype[k])) { | ||
result.push(k); | ||
} | ||
}); | ||
return result; | ||
} | ||
/** | ||
* Find all property on a given ES6 class | ||
* | ||
* @export | ||
* @param {*} target | ||
* @param {boolean} isSelfProperties | ||
* @returns {string[]} | ||
*/ | ||
function getPropertyNames(target, isSelfProperties = false) { | ||
const result = []; | ||
const enumerableOwnKeys = Object.getOwnPropertyNames(target); | ||
if (!isSelfProperties) { | ||
// searching prototype chain for methods | ||
let parent = ordinaryGetPrototypeOf(target); | ||
while (helper__namespace.isClass(parent) && parent.constructor) { | ||
const allOwnKeysOnPrototype = Object.getOwnPropertyNames(parent); | ||
// get methods from es6 class | ||
allOwnKeysOnPrototype.forEach((k) => { | ||
if (!result.includes(k) && !helper__namespace.isFunction(parent.prototype[k])) { | ||
result.push(k); | ||
} | ||
}); | ||
parent = ordinaryGetPrototypeOf(parent); | ||
} | ||
} | ||
// leave out those methods on Object's prototype | ||
enumerableOwnKeys.forEach((k) => { | ||
if (!result.includes(k) && !helper__namespace.isFunction(target.prototype[k])) { | ||
result.push(k); | ||
} | ||
}); | ||
return result; | ||
} | ||
/** | ||
* @ author: richen | ||
* @ copyright: Copyright (c) - <richenlin(at)gmail.com> | ||
* @ license: MIT | ||
* @ version: 2020-05-10 11:31:10 | ||
* @ version: 2020-05-10 11:03:58 | ||
*/ | ||
(0, tslib_1.__exportStar)(require("./Container"), exports); | ||
(0, tslib_1.__exportStar)(require("./IContainer"), exports); | ||
(0, tslib_1.__exportStar)(require("./Util"), exports); | ||
var Autowired_1 = require("./Autowired"); | ||
Object.defineProperty(exports, "Autowired", { enumerable: true, get: function () { return Autowired_1.Autowired; } }); | ||
var Value_1 = require("./Value"); | ||
Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return Value_1.Config; } }); | ||
Object.defineProperty(exports, "Value", { enumerable: true, get: function () { return Value_1.Value; } }); | ||
var AOP_1 = require("./AOP"); | ||
Object.defineProperty(exports, "AOPType", { enumerable: true, get: function () { return AOP_1.AOPType; } }); | ||
Object.defineProperty(exports, "Aspect", { enumerable: true, get: function () { return AOP_1.Aspect; } }); | ||
Object.defineProperty(exports, "Before", { enumerable: true, get: function () { return AOP_1.Before; } }); | ||
Object.defineProperty(exports, "BeforeEach", { enumerable: true, get: function () { return AOP_1.BeforeEach; } }); | ||
Object.defineProperty(exports, "After", { enumerable: true, get: function () { return AOP_1.After; } }); | ||
Object.defineProperty(exports, "AfterEach", { enumerable: true, get: function () { return AOP_1.AfterEach; } }); | ||
//# sourceMappingURL=index.js.map | ||
/** | ||
* Marks a constructor method as to be autowired by Koatty"s dependency injection facilities. | ||
* | ||
* @export | ||
* @param {string} [identifier] | ||
* @param {ComponentType} [type] | ||
* @param {any[]} [constructArgs] | ||
* @param {boolean} [isDelay=false] | ||
* @returns {PropertyDecorator} | ||
*/ | ||
function Autowired(identifier, type, constructArgs, isDelay = false) { | ||
return (target, propertyKey) => { | ||
const designType = Reflect.getMetadata("design:type", target, propertyKey); | ||
if (!identifier) { | ||
if (!designType || designType.name === "Object") { | ||
// throw Error("identifier cannot be empty when circular dependency exists"); | ||
identifier = helper__namespace.camelCase(propertyKey, true); | ||
} | ||
else { | ||
identifier = designType.name; | ||
} | ||
} | ||
if (!identifier) { | ||
throw Error("identifier cannot be empty when circular dependency exists"); | ||
} | ||
if (type === undefined) { | ||
if (identifier.indexOf("Controller") > -1) { | ||
type = "CONTROLLER"; | ||
} | ||
else if (identifier.indexOf("Middleware") > -1) { | ||
type = "MIDDLEWARE"; | ||
} | ||
else if (identifier.indexOf("Service") > -1) { | ||
type = "SERVICE"; | ||
} | ||
else { | ||
type = "COMPONENT"; | ||
} | ||
} | ||
//Cannot rely on injection controller | ||
if (type === "CONTROLLER") { | ||
throw new Error(`Controller cannot be injection!`); | ||
} | ||
//Cannot rely on injection middleware | ||
// if (type === "MIDDLEWARE") { | ||
// throw new Error(`Middleware ${identifier ?? ""} cannot be injected!`); | ||
// } | ||
if (!designType || designType.name === "Object") { | ||
isDelay = true; | ||
} | ||
IOCContainer.savePropertyData(TAGGED_PROP, { | ||
type, | ||
identifier, | ||
delay: isDelay, | ||
args: constructArgs !== null && constructArgs !== void 0 ? constructArgs : [] | ||
}, target, propertyKey); | ||
}; | ||
} | ||
/** | ||
* inject autowired class | ||
* | ||
* @export | ||
* @param {*} target | ||
* @param {*} instance | ||
* @param {Container} container | ||
* @param {boolean} [isLazy=false] | ||
*/ | ||
function injectAutowired(target, instance, container, isLazy = false) { | ||
var _a; | ||
const metaData = RecursiveGetMetadata(TAGGED_PROP, target); | ||
// tslint:disable-next-line: forin | ||
for (const metaKey in metaData) { | ||
let dep; | ||
const { type, identifier, delay, args } = metaData[metaKey] || { type: "", identifier: "", delay: false, args: [] }; | ||
if (type && identifier) { | ||
if (!delay || isLazy) { | ||
dep = container.get(identifier, type, args); | ||
if (dep) { | ||
// logger.Debug(`Register inject ${target.name} properties key: ${metaKey} => value: ${JSON.stringify(metaData[metaKey])}`); | ||
Reflect.defineProperty(instance, metaKey, { | ||
enumerable: true, | ||
configurable: false, | ||
writable: true, | ||
value: dep | ||
}); | ||
} | ||
else { | ||
throw new Error(`Component ${(_a = metaData[metaKey].identifier) !== null && _a !== void 0 ? _a : ""} not found. It's autowired in class ${target.name}`); | ||
} | ||
} | ||
else { | ||
// Delay loading solves the problem of cyclic dependency | ||
const app = container.getApp(); | ||
// tslint:disable-next-line: no-unused-expression | ||
if (app && app.once) { | ||
app.once("appReady", () => { | ||
// lazy inject autowired | ||
injectAutowired(target, instance, container, true); | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
/* | ||
* @Author: richen | ||
* @Date: 2020-12-18 10:37:03 | ||
* @LastEditors: Please set LastEditors | ||
* @LastEditTime: 2021-11-23 10:53:10 | ||
* @License: BSD (3-Clause) | ||
* @Copyright (c) - <richenlin(at)gmail.com> | ||
*/ | ||
/** | ||
* Indicates that an decorated configuration as a property. | ||
* | ||
* @export | ||
* @param {string} identifier configuration key | ||
* @param {string} [type] configuration type | ||
* @returns {PropertyDecorator} | ||
*/ | ||
function Value(key, type) { | ||
return (target, propertyKey) => { | ||
// ############### | ||
// PropertyDecorator is executed before ClassDecorator, resulting in that componentType cannot be obtained here... | ||
// ############### | ||
// const componentType = IOCContainer.getType(target); | ||
// if (componentType === "MIDDLEWARE") { | ||
// throw Error("Value decorator cannot be used in the middleware class. Please use app.config() to get the configuration."); | ||
// } | ||
// identifier = identifier || helper.camelCase(propertyKey, { pascalCase: true }); | ||
key = key || propertyKey; | ||
IOCContainer.savePropertyData(TAGGED_ARGS, `${key !== null && key !== void 0 ? key : ""}|${type || "config"}`, target, propertyKey); | ||
}; | ||
} | ||
/** | ||
* Indicates that an decorated configuration as a property. | ||
* | ||
* @export | ||
* @param {string} identifier configuration key | ||
* @param {string} [type] configuration type | ||
* @returns {PropertyDecorator} | ||
*/ | ||
const Config = Value; | ||
/** | ||
* | ||
* | ||
* @export | ||
* @param {*} target | ||
* @param {*} instance | ||
* @param {Container} container | ||
*/ | ||
function injectValue(target, instance, container) { | ||
// const componentType = IOCContainer.getType(target); | ||
// if (componentType === "MIDDLEWARE") { | ||
// throw Error("Value decorator cannot be used in the middleware class. Please use app.config() to get the configuration."); | ||
// } | ||
const app = container.getApp(); | ||
if (!app || !app.config) { | ||
return; | ||
} | ||
const metaData = RecursiveGetMetadata(TAGGED_ARGS, target); | ||
// tslint:disable-next-line: forin | ||
for (const metaKey in metaData) { | ||
// logger.Debug(`Register inject ${IOCContainer.getIdentifier(target)} config key: ${metaKey} => value: ${metaData[metaKey]}`); | ||
const propKeys = metaData[metaKey].split("|"); | ||
const [propKey, type] = propKeys; | ||
Reflect.defineProperty(instance, metaKey, { | ||
enumerable: true, | ||
configurable: false, | ||
writable: true, | ||
value: app.config(propKey, type) | ||
}); | ||
} | ||
} | ||
/** | ||
* @ author: richen | ||
* @ copyright: Copyright (c) - <richenlin(at)gmail.com> | ||
* @ license: BSD (3-Clause) | ||
* @ version: 2020-07-06 11:19:30 | ||
*/ | ||
/** | ||
* defined AOP type | ||
* | ||
* @export | ||
* @enum {number} | ||
*/ | ||
exports.AOPType = void 0; | ||
(function (AOPType) { | ||
AOPType["Before"] = "Before"; | ||
AOPType["BeforeEach"] = "BeforeEach"; | ||
AOPType["After"] = "After"; | ||
AOPType["AfterEach"] = "AfterEach"; | ||
})(exports.AOPType || (exports.AOPType = {})); | ||
/** | ||
* Indicates that an decorated class is a "aspect". | ||
* | ||
* @export | ||
* @param {string} [identifier] | ||
* @returns {ClassDecorator} | ||
*/ | ||
function Aspect(identifier) { | ||
return (target) => { | ||
identifier = identifier || IOCContainer.getIdentifier(target); | ||
if (!identifier.endsWith("Aspect")) { | ||
throw Error("Aspect class names must use a suffix `Aspect`."); | ||
} | ||
const oldMethod = Reflect.get(target.prototype, "run"); | ||
if (!oldMethod) { | ||
throw Error("The aspect class must implement the `run` method."); | ||
} | ||
IOCContainer.saveClass("COMPONENT", target, identifier); | ||
}; | ||
} | ||
/** | ||
* Executed before specifying the PointCut method. | ||
* | ||
* @export | ||
* @param {(string | Function)} aopName | ||
* @returns {MethodDecorator} | ||
*/ | ||
function Before(aopName) { | ||
return (target, methodName, descriptor) => { | ||
if (!aopName) { | ||
throw Error("AopName is required."); | ||
} | ||
// const { value, configurable, enumerable } = descriptor; | ||
// descriptor = { | ||
// configurable, | ||
// enumerable, | ||
// writable: true, | ||
// async value(...props: any[]) { | ||
// await executeAspect(aopName, props); | ||
// // tslint:disable-next-line: no-invalid-this | ||
// return value.apply(this, props); | ||
// }, | ||
// }; | ||
// return descriptor; | ||
IOCContainer.saveClassMetadata(TAGGED_CLS, TAGGED_AOP, { | ||
type: exports.AOPType.Before, | ||
name: aopName, | ||
method: methodName, | ||
}, target); | ||
}; | ||
} | ||
/** | ||
* Executed after execution of each method of the specified PointCut class. | ||
* | ||
* @export | ||
* @param {string} [aopName] | ||
* @returns {Function} | ||
*/ | ||
function BeforeEach(aopName) { | ||
return (target) => { | ||
IOCContainer.saveClassMetadata(TAGGED_CLS, TAGGED_AOP, { | ||
type: exports.AOPType.BeforeEach, | ||
name: aopName | ||
}, target); | ||
}; | ||
} | ||
/** | ||
* Executed after specifying the PointCut method. | ||
* | ||
* @export | ||
* @param {(string | Function)} aopName | ||
* @returns {MethodDecorator} | ||
*/ | ||
function After(aopName) { | ||
return (target, methodName, descriptor) => { | ||
if (!aopName) { | ||
throw Error("AopName is required."); | ||
} | ||
// const { value, configurable, enumerable } = descriptor; | ||
// descriptor = { | ||
// configurable, | ||
// enumerable, | ||
// writable: true, | ||
// async value(...props: any[]) { | ||
// // tslint:disable-next-line: no-invalid-this | ||
// const res = await value.apply(this, props); | ||
// await executeAspect(aopName, props); | ||
// return res; | ||
// } | ||
// }; | ||
// return descriptor; | ||
IOCContainer.saveClassMetadata(TAGGED_CLS, TAGGED_AOP, { | ||
type: exports.AOPType.After, | ||
name: aopName, | ||
method: methodName, | ||
}, target); | ||
}; | ||
} | ||
/** | ||
* Executed after execution of each method of the specified PointCut class. | ||
* | ||
* @export | ||
* @param {string} aopName | ||
* @returns {Function} | ||
*/ | ||
function AfterEach(aopName) { | ||
return (target) => { | ||
IOCContainer.saveClassMetadata(TAGGED_CLS, TAGGED_AOP, { | ||
type: exports.AOPType.AfterEach, | ||
name: aopName | ||
}, target); | ||
}; | ||
} | ||
/** | ||
* Execute aspect | ||
* | ||
* @param {(string | Function)} aopName | ||
* @param {any[]} props | ||
* @returns {*} | ||
*/ | ||
async function executeAspect(aopName, props) { | ||
// tslint:disable-next-line: one-variable-per-declaration | ||
let aspect; //, name = ""; | ||
if (helper__namespace.isClass(aopName)) { | ||
// tslint:disable-next-line: no-invalid-this | ||
aspect = IOCContainer.getInsByClass(aopName); | ||
// name = IOCContainer.getIdentifier(<Function>aopName) || (<Function>aopName).name || ""; | ||
} | ||
else { | ||
// tslint:disable-next-line: no-invalid-this | ||
aspect = IOCContainer.get(aopName, "COMPONENT"); | ||
// name = <string>aopName; | ||
} | ||
if (aspect && helper__namespace.isFunction(aspect.run)) { | ||
// logger.Info(`Execute the aspect ${name}`); | ||
// tslint:disable-next-line: no-invalid-this | ||
await aspect.run(props); | ||
} | ||
return Promise.resolve(); | ||
} | ||
/** | ||
* inject AOP | ||
* | ||
* @export | ||
* @param {*} target | ||
* @param {*} instance | ||
* @param {Container} container | ||
*/ | ||
function injectAOP(target, instance, container) { | ||
// If the class has defined the default AOP method, @BeforeEach and @AfterEach will not take effect | ||
const allMethods = getMethodNames(target); | ||
const methods = allMethods.filter((m) => !["constructor", "init", "__before", "__after"].includes(m) && target.prototype.hasOwnProperty(m)); | ||
if (allMethods.includes("__before") || allMethods.includes("__after")) { | ||
// inject default AOP method | ||
injectDefaultAOP(target, instance, methods); | ||
} | ||
else { | ||
const classMetaData = IOCContainer.getClassMetadata(TAGGED_CLS, TAGGED_AOP, target); | ||
if (classMetaData) { | ||
const { type, name, method } = classMetaData; | ||
if (name && [exports.AOPType.Before, exports.AOPType.BeforeEach, exports.AOPType.After, exports.AOPType.AfterEach].includes(type)) { | ||
methods.forEach((element) => { | ||
if ([exports.AOPType.Before, exports.AOPType.After].includes(type) && method === element) { | ||
// Logger.Debug(`Register inject AOP ${target.name} method: ${element} => ${type}`); | ||
defineAOPProperty(target, element, name, type); | ||
} | ||
else { | ||
// Logger.Debug(`Register inject AOP ${target.name} method: ${element} => ${type}`); | ||
defineAOPProperty(target, element, name, type); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
// /** | ||
// * Determine whether the class contains the default AOP method | ||
// * | ||
// * @param {*} target | ||
// * @returns {*} {boolean} | ||
// */ | ||
// function hasDefaultAOP(target: any): boolean { | ||
// const allMethods = getMethodNames(target).filter((m: string) => | ||
// !["constructor", "init"].includes(m) | ||
// ); | ||
// // class contains the default AOP method | ||
// if (allMethods.includes("__before") || allMethods.includes("__after")) { | ||
// return true; | ||
// } | ||
// return false; | ||
// } | ||
/** | ||
* inject default AOP | ||
* | ||
* @export | ||
* @param {*} target | ||
* @param {*} instance | ||
* @param {string[]} methods | ||
* @returns {*} | ||
*/ | ||
function injectDefaultAOP(target, instance, methods) { | ||
// class methods | ||
// const methods = getMethodNames(target, true).filter((m: string) => | ||
// !["constructor", "init", "__before", "__after"].includes(m) | ||
// ); | ||
// logger.Warn(`The ${target.name} class has a default AOP method, @BeforeEach and @AfterEach maybe not take effect`); | ||
methods.forEach((element) => { | ||
if (helper__namespace.isFunction(instance.__before)) { | ||
// logger.Debug(`Register inject default AOP ${target.name} method: ${element} => __before`); | ||
defineAOPProperty(target, element, "__before", exports.AOPType.BeforeEach); | ||
} | ||
if (helper__namespace.isFunction(instance.__after)) { | ||
// logger.Debug(`Register inject default AOP ${target.name} method: ${element} => __after`); | ||
defineAOPProperty(target, element, "__after", exports.AOPType.AfterEach); | ||
} | ||
}); | ||
} | ||
/** | ||
* Dynamically add methods for target class types | ||
* | ||
* @param {Function} classes | ||
* @param {string} protoName | ||
* @param {(string | Function)} aopName | ||
*/ | ||
function defineAOPProperty(classes, protoName, aopName, type) { | ||
const oldMethod = Reflect.get(classes.prototype, protoName); | ||
if (oldMethod) { | ||
Reflect.defineProperty(classes.prototype, protoName, { | ||
writable: true, | ||
async value(...props) { | ||
if ([exports.AOPType.Before, exports.AOPType.BeforeEach].includes(type)) { | ||
if (aopName === "__before") { | ||
// logger.Info(`Execute the aspect ${classes.name}.__before`); | ||
// tslint:disable-next-line: no-invalid-this | ||
await Reflect.apply(this.__before, this, props); | ||
} | ||
else { | ||
await executeAspect(aopName, props); | ||
} | ||
// tslint:disable-next-line: no-invalid-this | ||
return Reflect.apply(oldMethod, this, props); | ||
} | ||
else { | ||
// tslint:disable-next-line: no-invalid-this | ||
const res = await Reflect.apply(oldMethod, this, props); | ||
if (aopName === "__after") { | ||
// logger.Info(`Execute the aspect ${classes.name}.__after`); | ||
// tslint:disable-next-line: no-invalid-this | ||
await Reflect.apply(this.__after, this, props); | ||
} | ||
else { | ||
await executeAspect(aopName, props); | ||
} | ||
return res; | ||
} | ||
} | ||
}); | ||
} | ||
else { | ||
throw Error(`${protoName} method does not exist.`); | ||
} | ||
} | ||
/** | ||
* @ author: richen | ||
* @ copyright: Copyright (c) - <richenlin(at)gmail.com> | ||
* @ license: MIT | ||
* @ version: 2020-05-10 11:00:05 | ||
*/ | ||
/** | ||
* IOC Container | ||
* | ||
* @export | ||
* @class Container | ||
* @implements {IContainer} | ||
*/ | ||
class Container { | ||
/** | ||
* creates an instance of Container. | ||
* @param {*} app | ||
* @memberof Container | ||
*/ | ||
constructor() { | ||
this.classMap = new Map(); | ||
this.instanceMap = new WeakMap(); | ||
this.metadataMap = new WeakMap(); | ||
} | ||
/** | ||
* | ||
* | ||
* @static | ||
* @returns | ||
* @memberof ValidateUtil | ||
*/ | ||
static getInstance() { | ||
return this.instance || (this.instance = new Container()); | ||
} | ||
/** | ||
* set app | ||
* | ||
* @param {Koatty} app | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
setApp(app) { | ||
this.app = app; | ||
} | ||
/** | ||
* get app | ||
* | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getApp() { | ||
return this.app; | ||
} | ||
reg(identifier, target, options) { | ||
if (helper__namespace.isClass(identifier) || helper__namespace.isFunction(identifier)) { | ||
options = target; | ||
target = identifier; | ||
identifier = this.getIdentifier(target); | ||
} | ||
if (!helper__namespace.isClass(target)) { | ||
return target; | ||
} | ||
let instance = this.instanceMap.get(target); | ||
if (!instance) { | ||
options = { | ||
isAsync: false, | ||
initMethod: "constructor", | ||
destroyMethod: "distructor", | ||
scope: "Singleton", | ||
type: "COMPONENT", | ||
args: [], | ||
...options | ||
}; | ||
options.args = options.args.length ? options.args : []; | ||
// inject options once | ||
Reflect.defineProperty(target.prototype, "_options", { | ||
enumerable: false, | ||
configurable: false, | ||
writable: true, | ||
value: options | ||
}); | ||
// define app as getter | ||
const app = this.app; | ||
Reflect.defineProperty(target.prototype, "app", { | ||
get() { | ||
return app; | ||
}, | ||
configurable: false, | ||
enumerable: false | ||
}); | ||
// inject autowired | ||
injectAutowired(target, target.prototype, this); | ||
// inject value | ||
injectValue(target, target.prototype, this); | ||
// inject AOP | ||
injectAOP(target, target.prototype); | ||
const ref = this.getClass(options.type, identifier); | ||
if (!ref) { | ||
this.saveClass(options.type, target, identifier); | ||
} | ||
// instantiation | ||
instance = Reflect.construct(target, options.args); | ||
if (options.scope === "Singleton") { | ||
instance = Object.seal(instance); | ||
} | ||
// registration | ||
this.instanceMap.set(target, instance); | ||
} | ||
return instance; | ||
} | ||
/** | ||
* get instance from IOC container. | ||
* | ||
* @param {string} identifier | ||
* @param {ComponentType} [type="SERVICE"] | ||
* @param {any[]} [args=[]] | ||
* @returns {*} | ||
* @memberof Container | ||
*/ | ||
get(identifier, type = "SERVICE", args = []) { | ||
const target = this.getClass(identifier, type); | ||
if (!target) { | ||
return null; | ||
} | ||
// get instance from the Container | ||
const instance = this.instanceMap.get(target); | ||
// require Prototype instance | ||
if (args.length > 0) { | ||
// instantiation | ||
return Reflect.construct(target, args); | ||
} | ||
else { | ||
return instance; | ||
} | ||
} | ||
/** | ||
* get class from IOC container by identifier. | ||
* | ||
* @param {string} identifier | ||
* @param {ComponentType} [type="SERVICE"] | ||
* @returns {Function} | ||
* @memberof Container | ||
*/ | ||
getClass(identifier, type = "SERVICE") { | ||
return this.classMap.get(`${type}:${identifier}`); | ||
} | ||
/** | ||
* get instance from IOC container by class. | ||
* | ||
* @template T | ||
* @param {T} target | ||
* @param {any[]} [args=[]] | ||
* @returns {T} | ||
* @memberof Container | ||
*/ | ||
getInsByClass(target, args = []) { | ||
if (!helper__namespace.isClass(target)) { | ||
return null; | ||
} | ||
// get instance from the Container | ||
const instance = this.instanceMap.get(target); | ||
// require Prototype instance | ||
if (args.length > 0) { | ||
// instantiation | ||
return Reflect.construct(target, args); | ||
} | ||
else { | ||
return instance; | ||
} | ||
} | ||
/** | ||
* get metadata from class | ||
* | ||
* @static | ||
* @param {(string | symbol)} metadataKey | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} [propertyKey] | ||
* @returns | ||
* @memberof Injectable | ||
*/ | ||
getMetadataMap(metadataKey, target, propertyKey) { | ||
// filter Object.create(null) | ||
if (typeof target === "object" && target.constructor) { | ||
target = target.constructor; | ||
} | ||
if (!this.metadataMap.has(target)) { | ||
this.metadataMap.set(target, new Map()); | ||
} | ||
if (propertyKey) { | ||
// for property or method | ||
const key = `${helper__namespace.toString(metadataKey)}:${helper__namespace.toString(propertyKey)}`; | ||
const map = this.metadataMap.get(target); | ||
if (!map.has(key)) { | ||
map.set(key, new Map()); | ||
} | ||
return map.get(key); | ||
} | ||
else { | ||
// for class | ||
const map = this.metadataMap.get(target); | ||
if (!map.has(metadataKey)) { | ||
map.set(metadataKey, new Map()); | ||
} | ||
return map.get(metadataKey); | ||
} | ||
} | ||
/** | ||
* get identifier from class | ||
* | ||
* @param {Function | Object} target | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getIdentifier(target) { | ||
var _a, _b, _c; | ||
let name = ""; | ||
if (helper__namespace.isFunction(target)) { | ||
const metaData = Reflect.getOwnMetadata(TAGGED_CLS, target); | ||
if (metaData) { | ||
name = (_a = metaData.id) !== null && _a !== void 0 ? _a : ""; | ||
} | ||
else { | ||
name = (_b = target.name) !== null && _b !== void 0 ? _b : ""; | ||
} | ||
} | ||
else { | ||
name = target.constructor ? ((_c = target.constructor.name) !== null && _c !== void 0 ? _c : "") : ""; | ||
} | ||
return name; | ||
} | ||
/** | ||
* get component type from class | ||
* | ||
* @param {Function} target | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getType(target) { | ||
var _a, _b; | ||
const metaData = Reflect.getOwnMetadata(TAGGED_CLS, target); | ||
if (metaData) { | ||
return metaData.type; | ||
} | ||
else { | ||
let name = (_a = target.name) !== null && _a !== void 0 ? _a : ""; | ||
name = name || (target.constructor ? ((_b = target.constructor.name) !== null && _b !== void 0 ? _b : "") : ""); | ||
if (~name.indexOf("Controller")) { | ||
return "CONTROLLER"; | ||
} | ||
else if (~name.indexOf("Middleware")) { | ||
return "MIDDLEWARE"; | ||
} | ||
else if (~name.indexOf("Service")) { | ||
return "SERVICE"; | ||
} | ||
else { | ||
return "COMPONENT"; | ||
} | ||
} | ||
} | ||
/** | ||
* save class to Container | ||
* | ||
* @param {ComponentType} type | ||
* @param {Function} module | ||
* @param {string} identifier | ||
* @memberof Container | ||
*/ | ||
saveClass(type, module, identifier) { | ||
Reflect.defineMetadata(TAGGED_CLS, { id: identifier, type }, module); | ||
const key = `${type}:${identifier}`; | ||
if (!this.classMap.has(key)) { | ||
this.classMap.set(key, module); | ||
} | ||
} | ||
/** | ||
* get all class from Container | ||
* | ||
* @param {ComponentType} type | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
listClass(type) { | ||
const modules = []; | ||
this.classMap.forEach((v, k) => { | ||
if (k.startsWith(type)) { | ||
modules.push({ | ||
id: k, | ||
target: v | ||
}); | ||
} | ||
}); | ||
return modules; | ||
} | ||
/** | ||
* save meta data to class or property | ||
* | ||
* @param {string} type | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {string} [propertyName] | ||
* @memberof Container | ||
*/ | ||
saveClassMetadata(type, decoratorNameKey, data, target, propertyName) { | ||
if (propertyName) { | ||
const originMap = this.getMetadataMap(type, target, propertyName); | ||
originMap.set(decoratorNameKey, data); | ||
} | ||
else { | ||
const originMap = this.getMetadataMap(type, target); | ||
originMap.set(decoratorNameKey, data); | ||
} | ||
} | ||
/** | ||
* attach data to class or property | ||
* | ||
* @param {string} type | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {string} [propertyName] | ||
* @memberof Container | ||
*/ | ||
attachClassMetadata(type, decoratorNameKey, data, target, propertyName) { | ||
let originMap; | ||
if (propertyName) { | ||
originMap = this.getMetadataMap(type, target, propertyName); | ||
} | ||
else { | ||
originMap = this.getMetadataMap(type, target); | ||
} | ||
if (!originMap.has(decoratorNameKey)) { | ||
originMap.set(decoratorNameKey, []); | ||
} | ||
originMap.get(decoratorNameKey).push(data); | ||
} | ||
/** | ||
* get single data from class or property | ||
* | ||
* @param {string} type | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {(Function | object)} target | ||
* @param {string} [propertyName] | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getClassMetadata(type, decoratorNameKey, target, propertyName) { | ||
if (propertyName) { | ||
const originMap = this.getMetadataMap(type, target, propertyName); | ||
return originMap.get(decoratorNameKey); | ||
} | ||
else { | ||
const originMap = this.getMetadataMap(type, target); | ||
return originMap.get(decoratorNameKey); | ||
} | ||
} | ||
/** | ||
* save property data to class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} propertyName | ||
* @memberof Container | ||
*/ | ||
savePropertyData(decoratorNameKey, data, target, propertyName) { | ||
const originMap = this.getMetadataMap(decoratorNameKey, target); | ||
originMap.set(propertyName, data); | ||
} | ||
/** | ||
* attach property data to class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {*} data | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} propertyName | ||
* @memberof Container | ||
*/ | ||
attachPropertyData(decoratorNameKey, data, target, propertyName) { | ||
const originMap = this.getMetadataMap(decoratorNameKey, target); | ||
if (!originMap.has(propertyName)) { | ||
originMap.set(propertyName, []); | ||
} | ||
originMap.get(propertyName).push(data); | ||
} | ||
/** | ||
* get property data from class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {(Function | object)} target | ||
* @param {(string | symbol)} propertyName | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
getPropertyData(decoratorNameKey, target, propertyName) { | ||
const originMap = this.getMetadataMap(decoratorNameKey, target); | ||
return originMap.get(propertyName); | ||
} | ||
/** | ||
* list property data from class | ||
* | ||
* @param {(string | symbol)} decoratorNameKey | ||
* @param {(Function | object)} target | ||
* @returns | ||
* @memberof Container | ||
*/ | ||
listPropertyData(decoratorNameKey, target) { | ||
const originMap = this.getMetadataMap(decoratorNameKey, target); | ||
const datas = {}; | ||
for (const [key, value] of originMap) { | ||
datas[key] = value; | ||
} | ||
return datas; | ||
} | ||
} | ||
// export Singleton | ||
const IOCContainer = Container.getInstance(); | ||
exports.After = After; | ||
exports.AfterEach = AfterEach; | ||
exports.Aspect = Aspect; | ||
exports.Autowired = Autowired; | ||
exports.Before = Before; | ||
exports.BeforeEach = BeforeEach; | ||
exports.Config = Config; | ||
exports.Container = Container; | ||
exports.IOCContainer = IOCContainer; | ||
exports.RecursiveGetMetadata = RecursiveGetMetadata; | ||
exports.TAGGED_AOP = TAGGED_AOP; | ||
exports.TAGGED_ARGS = TAGGED_ARGS; | ||
exports.TAGGED_CLS = TAGGED_CLS; | ||
exports.TAGGED_METHOD = TAGGED_METHOD; | ||
exports.TAGGED_PROP = TAGGED_PROP; | ||
exports.Value = Value; | ||
exports.getMethodNames = getMethodNames; | ||
exports.getPropertyNames = getPropertyNames; |
@@ -28,4 +28,2 @@ /** | ||
'ts-jest': { | ||
// 是否使用 babel 配置来转译 | ||
babelConfig: true, | ||
// 编译 Typescript 所依赖的配置 | ||
@@ -32,0 +30,0 @@ tsconfig: '<rootDir>/tsconfig.json', |
{ | ||
"name": "koatty_container", | ||
"version": "1.6.11", | ||
"version": "1.6.12", | ||
"description": "IOC Container for Koatty.", | ||
"scripts": { | ||
"build": "del-cli --force dist && tsc", | ||
"build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp", | ||
"build:cp": "node scripts/postBuild && copyfiles package.json LICENSE README.md dist/", | ||
"build:js": "del-cli --force dist && npx rollup -c", | ||
"build:doc": "del-cli --force docs/api && npx api-documenter markdown --input temp --output docs/api", | ||
"build:dts": "del-cli --force lib && npx tsc && npx api-extractor run --local --verbose && del-cli --force lib", | ||
"eslint": "eslint --ext .ts,.js ./", | ||
"prepublishOnly": "npm test && npm run build", | ||
"release": "npm run prepublishOnly && standard-version", | ||
"prerelease": "npm test && npm run build", | ||
"release": "standard-version", | ||
"release:pre": "npm run release -- --prerelease", | ||
"release:major": "npm run release -- --release-as major", | ||
"release:minor": "npm run release -- --release-as minor", | ||
"pub": "git push --follow-tags origin && npm publish", | ||
"pub:pre": "git push --follow-tags origin && npm publish --tag prerelease", | ||
"test": "npm run eslint && jest --passWithNoTests", | ||
@@ -44,8 +53,5 @@ "test:cov": "jest --collectCoverage --detectOpenHandles", | ||
"devDependencies": { | ||
"@babel/core": "^7.x.x", | ||
"@babel/plugin-proposal-decorators": "^7.x.x", | ||
"@babel/preset-env": "^7.x.x", | ||
"@babel/preset-typescript": "^7.x.x", | ||
"@commitlint/cli": "^12.x.x", | ||
"@commitlint/config-conventional": "^15.x.x", | ||
"@microsoft/api-documenter": "^7.x.x", | ||
"@microsoft/api-extractor": "^7.x.x", | ||
"@rollup/plugin-json": "^4.x.x", | ||
"@types/jest": "^27.x.x", | ||
@@ -56,3 +62,6 @@ "@types/koa": "^2.x.x", | ||
"@typescript-eslint/parser": "^5.x.x", | ||
"commitlint": "^15.x.x", | ||
"commitlint-config-gitmoji": "^2.x.x", | ||
"conventional-changelog-cli": "^2.x.x", | ||
"copyfiles": "^2.x.x", | ||
"del-cli": "^4.x.x", | ||
@@ -64,2 +73,4 @@ "eslint": "^8.x.x", | ||
"jest-html-reporters": "^2.x.x", | ||
"rollup": "^2.x.x", | ||
"rollup-plugin-typescript2": "^0.x.x", | ||
"standard-version": "^9.x.x", | ||
@@ -80,2 +91,2 @@ "ts-jest": "^27.x.x", | ||
} | ||
} | ||
} |
@@ -14,5 +14,6 @@ { | ||
"declaration": true /* Generates corresponding '.d.ts' file. */, | ||
"declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||
"sourceMap": true /* Generates corresponding '.map' file. */, | ||
// "outFile": "./", /* Concatenate and emit output to single file. */ | ||
"outDir": "./dist/" /* Redirect output structure to the directory. */, | ||
"outDir": "./lib" /* Redirect output structure to the directory. */, | ||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||
@@ -25,3 +26,3 @@ "removeComments": false /* Do not emit comments to output. */, | ||
/* Strict Type-Checking Options */ | ||
"stripInternal": true /* Enable all strict type-checking options. */, | ||
"stripInternal": true, /* Enable all strict type-checking options. */ | ||
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, | ||
@@ -53,2 +54,3 @@ // "strictNullChecks": true, /* Enable strict null checks. */ | ||
"esModuleInterop": true, | ||
"useUnknownInCatchVariables": false, /* Default catch clause variables as unknown instead of any. */ | ||
/* Source Map Options */ | ||
@@ -55,0 +57,0 @@ // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2131442
116
8063
24
1
1