v0.6.0: 收单入口
- 类型契约/Express 装配/MongoShrimp 全部合并进 src/main/index.ts - 删 src/main/expmon.ts、src/main/types.ts - package.json exports 收成只剩 "."(和 ./package.json) - IShrimpType.ts 头加 @contractVersion 1.0.0(供 shrimp-admin 副本对照) 未上生产,直接断掉 shrimp-server/expmon、shrimp-server/types 两个子入口。
This commit is contained in:
+1
-9
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "shrimp-server",
|
||||
"version": "0.5.0",
|
||||
"version": "0.6.0",
|
||||
"private": true,
|
||||
"description": "Shrimp 框架后端 — 声明式字段驱动的 Node.js 管理后台框架(Express + Mongoose + JWT)",
|
||||
"main": "src/main/index.ts",
|
||||
@@ -10,14 +10,6 @@
|
||||
"types": "./src/main/index.ts",
|
||||
"default": "./src/main/index.ts"
|
||||
},
|
||||
"./expmon": {
|
||||
"types": "./src/main/expmon.ts",
|
||||
"default": "./src/main/expmon.ts"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./src/main/types.ts",
|
||||
"default": "./src/main/types.ts"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
|
||||
+8
-2
@@ -1,6 +1,12 @@
|
||||
/**
|
||||
* Shrimp 前后端共用类型定义
|
||||
* 定义错误码、协议、通用数据格式
|
||||
* Shrimp 类型契约 — 前后端 wire protocol 定义
|
||||
*
|
||||
* @contractVersion 1.0.0
|
||||
*
|
||||
* 改动此文件需要:
|
||||
* 1. 升 @contractVersion(语义化版本)
|
||||
* 2. 同步到 shrimp-admin/src/IShrimpType.ts,更新其 @syncedFrom
|
||||
* 3. 通知消费侧对齐
|
||||
*/
|
||||
|
||||
/** 业务错误码 */
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
* 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 || ""
|
||||
}
|
||||
}
|
||||
+95
-12
@@ -1,19 +1,28 @@
|
||||
/**
|
||||
* Shrimp 核心入口 — 0 重依赖
|
||||
* Shrimp 单一入口 — 完整后端栈
|
||||
*
|
||||
* 只暴露 Shrimp 框架本体 + 内存数据源 + 类型定义,不引入
|
||||
* express / mongoose / jsonwebtoken。bcrypt 是 lazy import,
|
||||
* 不走 Password 字段就不会触发。
|
||||
* 包含框架核心 + 类型契约 + Express + Mongoose + JWT 装配体。
|
||||
*
|
||||
* 适用场景:
|
||||
* - 只想用 Shrimp 的 RPC dispatch + 模块/字段声明 + 内存 CRUD
|
||||
* - 自己接 HTTP / 自己写存储层
|
||||
* - 跑测试 / 跑无 DB 的 demo
|
||||
* 安装 peer:express / mongoose / jsonwebtoken / bcrypt。
|
||||
*
|
||||
* 需要完整后台(Express + Mongoose + JWT)请从 'shrimp-server/expmon' 导入。
|
||||
* 前端只想要类型契约,**不要**从这里 import — 见 shrimp-admin 的
|
||||
* IShrimpType.ts(契约副本),避免把 mongoose/express 牵进前端 bundle。
|
||||
*
|
||||
* 想换掉其中一块的高级用法:
|
||||
* - 自己造 ITokenAuth(看 createJwtTokenAuth 实现)
|
||||
* - 自己造 dataSource(实现 ShrimpCrud 接口)
|
||||
* - 直接 buildShrimpRouter(deps) 拼自己的 Express app,绕开 ShrimpServer
|
||||
*/
|
||||
|
||||
// ===== 类型 / 接口 / 枚举 =====
|
||||
import { Router } from "express"
|
||||
import { MongoShrimp } 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"
|
||||
|
||||
// ===== 类型契约 / 枚举 =====
|
||||
export {
|
||||
ShrimpCode,
|
||||
ShrimpError,
|
||||
@@ -64,9 +73,83 @@ export type { ShrimpCrud } from "../Shrimp/ShrimpCrud"
|
||||
export { UserModule, RoleModule } from "../Shrimp/UserRoleModule"
|
||||
export { OperationLogModule } from "../Shrimp/OperationLogModule"
|
||||
|
||||
// ===== 密码哈希(可注入,默认 bcrypt lazy import) =====
|
||||
// ===== 密码哈希 =====
|
||||
export { bcryptHasher, plainHasher } from "../PasswordHasher"
|
||||
export type { IPasswordHasher } from "../PasswordHasher"
|
||||
|
||||
// ===== 数据源(纯内存,无外部依赖) =====
|
||||
// ===== 数据源 =====
|
||||
export { MemoryShrimpCrud } from "../MemoryShrimpCrud"
|
||||
export { MongoShrimp, UserSchema, RoleSchema, OperationLogSchema } from "../forMongo/MongoShrimp"
|
||||
export { MongoShrimpCrud } from "../forMongo/MongoShrimpCrud"
|
||||
|
||||
// ===== Express 装配 =====
|
||||
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 || ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Shrimp 纯类型入口
|
||||
*
|
||||
* 只导出 IShrimpType.ts 的全部协议(类型 + ShrimpCode enum + ShrimpError class),
|
||||
* 前端 shrimp-admin / 任何只需要协议定义的消费方从这里 import,
|
||||
* 不会触发任何运行时依赖。
|
||||
*/
|
||||
|
||||
export * from "../IShrimpType"
|
||||
Reference in New Issue
Block a user