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
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
2131442
116
8063
24
1
1