@lakutata/core
Version:
Lakutata Framework Core
146 lines (136 loc) • 4.16 kB
text/typescript
import {Injectable} from '../decorators/DependencyInjection'
import {IConstructor} from '../interfaces/IConstructor'
import {Exception} from './abstracts/Exception'
import {CONFIGURABLE_NAMES} from '../constants/MetadataKeys'
export class BaseObject {
/**
* 获取类路径
* @returns {string}
*/
public get classPath(): string {
const cachedModules = require('module')._cache
for (const modulePath of Object.keys(cachedModules)) {
if (cachedModules[modulePath] && typeof cachedModules[modulePath] === 'object' && cachedModules[modulePath].exports && typeof exports === 'object') {
for (const exportName of Object.keys(cachedModules[modulePath].exports)) {
if (cachedModules[modulePath].exports[exportName] === this.constructor) {
return modulePath
}
}
}
}
return ''
}
/**
* 获取类名
* @returns {string}
*/
public get className(): string {
return this.constructor.name
}
/**
* 判断类中是否存在方法
* @param {string} name
* @returns {boolean}
*/
public hasMethod(name: string) {
let candidate
if (this.hasProperty(name) || !!this[name]) {
candidate = this[name]
} else {
return false
}
return typeof candidate === 'function'
}
/**
* 是否拥有指定的属性
* @param {string} name
* @returns {boolean}
*/
public hasProperty(name: string): boolean {
return this.hasOwnProperty(name) || this.getConfigurablePropertyNames().includes(name)
}
/**
* 设置属性
* @param {string} name
* @param value
* @param {"overwrite" | "partial"} mode
* @returns {boolean}
*/
public setProperty(name: string, value: any, mode: 'overwrite' | 'partial' = 'overwrite'): boolean {
if (this.hasProperty(name)) {
switch (mode) {
case 'overwrite': {
this[name] = value
return true
}
case 'partial': {
if (typeof this[name] === typeof value && Array.isArray(value) && Array.isArray(this[name])) {
this[name] = Array.from(new Set(this[name].concat(value)))
} else if (typeof this[name] === typeof value && typeof this[name] === 'object') {
this[name] = Object.assign(this[name], value)
} else {
this[name] = value
}
return true
}
default: {
return false
}
}
}
this[name] = value
return true
}
/**
* 定义属性
* @param {PropertyKey} p
* @param {PropertyDescriptor} attributes
*/
public defineProperty(p: PropertyKey, attributes: PropertyDescriptor & ThisType<this>): void {
Object.defineProperty(this, p, attributes)
}
/**
* 获取可配置属性名称数组
* @returns {string[]}
*/
public getConfigurablePropertyNames(): string[] {
const configurableProperties: string[] = Reflect.getMetadata(CONFIGURABLE_NAMES, this)
if (!configurableProperties) return []
return configurableProperties
}
/**
* 获取属性值
* @param {string} name
* @param defaultValue
* @returns {any}
*/
public getProperty(name: string, defaultValue: any = undefined): any {
if (this.hasProperty(name)) return this[name]
return defaultValue
}
public generateException(...args: any[]): Exception
public generateException(exceptionConstructor: IConstructor<Exception>, ...args: any[]): Exception
public generateException(exceptionConstructorOrArgument: IConstructor<Exception> | any, ...args: any[]): Exception {
const self = this
let exceptionInstance: Exception
if (typeof exceptionConstructorOrArgument === 'function') {
exceptionInstance = new exceptionConstructorOrArgument(args)
exceptionInstance.district = self.className
} else {
const exceptionArguments: any[] = [exceptionConstructorOrArgument].concat(args)
const exceptionName: string = `${this.className}Exception`
const generatedExceptionConstructor = class extends Exception {
public errno: number
public district: string = self.className
protected exceptionName: string = exceptionName
public readonly err: string = exceptionName
public get name(): string {
return exceptionName
}
}
exceptionInstance = new generatedExceptionConstructor(exceptionArguments)
}
return exceptionInstance
}
}