v0.5.0: 重新组织目录结构,按职责拆分
- 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)
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Shrimp expmon 入口 — Express + Mongoose 整合方案
|
||||
*
|
||||
* 在 core 之上把 forMongo(MongoShrimp + 数据源)和 forExpress(buildShrimpRouter
|
||||
* + JWT)拼起来,导出开箱即用的 ShrimpServer 装配体。
|
||||
*
|
||||
* 这一入口需要消费方安装 peer:express / mongoose / jsonwebtoken / bcrypt。
|
||||
* 不需要时改从 'shrimp-server' 导入,不会触发任何 peer。
|
||||
*
|
||||
* 想换掉其中一块的高级用法:
|
||||
* - 自己造 ITokenAuth(看 createJwtTokenAuth 实现)
|
||||
* - 自己造 dataSource(实现 ShrimpCrud 接口)
|
||||
* - 直接 buildShrimpRouter(deps) 拼自己的 Express app,绕开本类
|
||||
*/
|
||||
|
||||
import { Router } from "express"
|
||||
import { MongoShrimp, UserSchema, RoleSchema, OperationLogSchema } from "../forMongo/MongoShrimp"
|
||||
import { buildShrimpRouter } from "../forExpress/buildShrimpRouter"
|
||||
import { createJwtTokenAuth } from "../forExpress/jwtAuth"
|
||||
import type { ITokenAuth, IUserAccessor } from "../forExpress/types"
|
||||
import type { RootShrimpPower } from "../Shrimp/ShrimpPower"
|
||||
import type { IUser, IRole, WithId } from "../IShrimpType"
|
||||
|
||||
// 再导出所有 core 的符号,'shrimp-server/expmon' 单一入口就够用
|
||||
export * from "./index"
|
||||
|
||||
// ===== forMongo / forExpress 公开符号 =====
|
||||
export { MongoShrimp, UserSchema, RoleSchema, OperationLogSchema } from "../forMongo/MongoShrimp"
|
||||
export { MongoShrimpCrud } from "../forMongo/MongoShrimpCrud"
|
||||
export { buildShrimpRouter } from "../forExpress/buildShrimpRouter"
|
||||
export { createJwtTokenAuth } from "../forExpress/jwtAuth"
|
||||
export type { IJwtTokenAuthOptions } from "../forExpress/jwtAuth"
|
||||
export type { ITokenAuth, IUserAccessor, IShrimpRouterDeps } from "../forExpress/types"
|
||||
|
||||
// ============== ShrimpServer ==============
|
||||
|
||||
export class ShrimpServer extends MongoShrimp implements IUserAccessor {
|
||||
router: Router
|
||||
jwtSecret: string
|
||||
config: Record<string, any>
|
||||
globalOptions: Record<string, any> = {}
|
||||
forcedOptionAccess = new Map<string, RootShrimpPower>()
|
||||
|
||||
constructor(jwtSecret: string, config: Record<string, any> = {}, mongodbUri: string = "mongodb://localhost:27017/shrimp") {
|
||||
super(mongodbUri)
|
||||
this.jwtSecret = jwtSecret
|
||||
this.config = config
|
||||
|
||||
this.router = buildShrimpRouter({
|
||||
shrimp: this,
|
||||
userModule: this.userModule,
|
||||
roleModule: this.roleModule,
|
||||
operationLogModule: this.operationLogModule,
|
||||
tokenAuth: this.createTokenAuth(),
|
||||
config: this.config,
|
||||
globalOptions: this.globalOptions,
|
||||
forcedOptionAccess: this.forcedOptionAccess,
|
||||
userAccessor: this,
|
||||
})
|
||||
}
|
||||
|
||||
registerOptions(key: string, options: any, access?: RootShrimpPower) {
|
||||
this.globalOptions[key] = options
|
||||
if (access) {
|
||||
this.forcedOptionAccess.set(key, access)
|
||||
}
|
||||
}
|
||||
|
||||
/** 创建 Token 鉴权,默认 JWT。子类可覆盖换成 session 之类。 */
|
||||
protected createTokenAuth(): ITokenAuth {
|
||||
return createJwtTokenAuth(this.jwtSecret)
|
||||
}
|
||||
|
||||
// ============== 可覆盖的用户/角色字段访问钩子(实现 IUserAccessor) ==============
|
||||
|
||||
getJwtPayload(user: WithId<IUser>): Record<string, any> {
|
||||
return { _id: user._id, roleId: user.roleId }
|
||||
}
|
||||
|
||||
isUserActive(user: WithId<IUser>): boolean {
|
||||
return user.active === true
|
||||
}
|
||||
|
||||
getUserRoleIds(user: WithId<IUser>): string[] {
|
||||
return Array.isArray(user.roleId) ? user.roleId.map(String) : user.roleId ? [String(user.roleId)] : []
|
||||
}
|
||||
|
||||
isRoleSuperAdmin(role: WithId<IRole> | null): boolean {
|
||||
return !!role?.isSuperAdmin
|
||||
}
|
||||
|
||||
getRolePowers(role: WithId<IRole> | null): string[] {
|
||||
return role?.powers || []
|
||||
}
|
||||
|
||||
getUserDisplayName(user: WithId<IUser>): string {
|
||||
return user.nickname || ""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user