- Shrimp.ts (875 行) 按类拆分到 Shrimp/(7 文件: Shrimp, ShrimpModule, ShrimpTableModule, ShrimpPower, ShrimpCrud, UserRoleModule, OperationLogModule) - forMongo/: MongoShrimpCrud + MongoShrimp(原 ShrimpServer 的 mongo 装配部分,无 express) - forExpress/: buildShrimpRouter + jwtAuth + types - main/: index(0 依赖核心) + expmon(express+mongo 整合,导出 ShrimpServer) + types(纯协议) - 入口子路径 server → expmon(express+mongo 整合方案命名更准确) - 删除冗余的 index.ts / core.ts(合并为 main/index.ts)
94 lines
3.3 KiB
TypeScript
94 lines
3.3 KiB
TypeScript
import type { IFieldConfig, ILabel } from "../IShrimpType"
|
|
import { Shrimp } from "./Shrimp"
|
|
import { RootShrimpPower, ShrimpPower } from "./ShrimpPower"
|
|
|
|
type ShrimpEventHandler = (...args: any[]) => Promise<any>
|
|
|
|
export class ShrimpEvent {
|
|
constructor(public name: string, public handler: ShrimpEventHandler, public power: RootShrimpPower) {
|
|
}
|
|
}
|
|
|
|
export interface IShrimpModuleOptions {
|
|
icon?: string
|
|
ownerKey?: string
|
|
}
|
|
|
|
export class ShrimpModule<P extends Record<string, any> = Record<string, any>> {
|
|
power: RootShrimpPower
|
|
root: Shrimp
|
|
modules: Map<string, ShrimpModule> = new Map()
|
|
events: Map<string, ShrimpEvent> = new Map()
|
|
icon?: string
|
|
ownerKey?: string
|
|
constructor(public parent: Shrimp | ShrimpModule, public moduleKey: string, public label: ILabel, power?: RootShrimpPower, options?: IShrimpModuleOptions) {
|
|
if (power == null) {
|
|
if (parent instanceof Shrimp) {
|
|
power = new RootShrimpPower(moduleKey, label)
|
|
}
|
|
else {
|
|
power = new ShrimpPower(parent.power, moduleKey, label)
|
|
}
|
|
}
|
|
this.power = power
|
|
this.icon = options?.icon
|
|
this.ownerKey = options?.ownerKey
|
|
parent.modules.set(this.moduleKey, this)
|
|
this.root = parent.root
|
|
}
|
|
addEvent<K extends keyof P & string>(name: K, label: ILabel): this
|
|
addEvent<K extends keyof P & string>(name: K, power: RootShrimpPower): this
|
|
addEvent<K extends keyof P & string>(name: K, powerOrLabel: RootShrimpPower | ILabel) {
|
|
const handler = (this as any)[name]
|
|
if (typeof handler !== 'function') {
|
|
throw new Error(`Method "${name}" not found on ${this.moduleKey}`)
|
|
}
|
|
let power: RootShrimpPower
|
|
if (powerOrLabel instanceof RootShrimpPower) {
|
|
power = powerOrLabel
|
|
} else {
|
|
power = new ShrimpPower(this.power, name, powerOrLabel)
|
|
}
|
|
this.events.set(name, new ShrimpEvent(name, handler.bind(this), power))
|
|
return this
|
|
}
|
|
async call(path: string[], ...args: any[]): Promise<any> {
|
|
if (path.length > 1) {
|
|
let module = this.modules.get(path[0])
|
|
if (module == null) {
|
|
throw new Error(`Module "${path[0]}" not found`)
|
|
}
|
|
return await module.call(path.slice(1), ...args)
|
|
} else {
|
|
const event = this.events.get(path[0])
|
|
if (event == null) {
|
|
throw new Error(`Event "${path[0]}" not found`)
|
|
}
|
|
return await event.handler(...args)
|
|
}
|
|
}
|
|
getEventInfo(powers: Set<string>): string[] {
|
|
let events: string[] = []
|
|
this.events.forEach(event => {
|
|
if (powers.has(event.power.key)) {
|
|
events.push(event.name)
|
|
}
|
|
})
|
|
return events
|
|
}
|
|
checkEvent(powers: Set<string>, path: string[]): boolean {
|
|
if (path.length > 1) {
|
|
let module = this.modules.get(path[0])
|
|
if (module == null) return false
|
|
return module.checkEvent(powers, path.slice(1))
|
|
} else {
|
|
const event = this.events.get(path[0])
|
|
if (event == null) return false
|
|
return powers.has(event.power.key)
|
|
}
|
|
}
|
|
getFields(): IFieldConfig[] {
|
|
return []
|
|
}
|
|
}
|