@linyjs/plugin-docs 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -65,28 +65,28 @@ npx @linyjs/cli example blog-plugin -o ./my-blog
65
65
 
66
66
  ```
67
67
  docs/
68
- ├── getting-started/ # 入门教程
69
- │ ├── quick-start.md # 快速开始
70
- │ ├── installation.md # 安装指南
71
- │ └── first-plugin.md # 第一个插件
72
- ├── guides/ # 进阶指南
73
- │ ├── server-module.md # 服务端模块
74
- │ ├── client-module.md # 客户端模块
75
- │ ├── ui-slots.md # UI扩展插槽
76
- │ ├── permissions.md # 权限管理
77
- │ ├── data-persistence.md # 数据持久化
78
- └── authentication.md # 用户认证
79
- ├── api-reference/ # API参考
80
- ├── server-interface.md
81
- ├── client-interface.md
82
- │ └── ui-slots-interface.md
83
- ├── best-practices/ # 最佳实践
68
+ ├── getting-started/ # 入门教程
69
+ │ ├── quick-start.md # 快速开始
70
+ │ ├── installation.md # 安装指南
71
+ │ └── first-plugin.md # 第一个插件
72
+ ├── guides/ # 进阶指南
73
+ │ ├── server-module.md # 服务端模块
74
+ │ ├── dependency-injection.md # 依赖注入机制
75
+ │ ├── shared-module-interface.md # shared-module-interface 类型包
76
+ │ ├── client-module.md # 客户端模块
77
+ │ ├── ui-slots.md # UI扩展插槽
78
+ ├── permissions.md # 权限管理
79
+ ├── data-persistence.md # 数据持久化
80
+ └── authentication.md # 用户认证
81
+ ├── api-reference/ # API参考
82
+ │ └── index.md # 接口定义(含依赖注入接口)
83
+ ├── best-practices/ # 最佳实践
84
84
  │ ├── naming-conventions.md
85
85
  │ ├── service-definition.md # ServiceDef 代码风格规范
86
86
  │ ├── error-handling.md
87
87
  │ ├── performance.md
88
88
  │ └── security.md
89
- └── faq.md # 常见问题
89
+ └── faq.md # 常见问题
90
90
  ```
91
91
 
92
92
  ## 💡 示例项目
@@ -128,6 +128,8 @@ linyjs 提供了以下核心模块,插件可以通过依赖注入方式调用
128
128
 
129
129
  ## 📖 核心模块指南
130
130
 
131
+ - 📖 [依赖注入机制](./docs/guides/dependency-injection.md) — linyjs DI 机制完整说明
132
+ - 📦 [shared-module-interface](./docs/guides/shared-module-interface.md) — 类型定义包使用说明
131
133
  - 💾 [数据持久化](./docs/guides/data-persistence.md) - 使用 @linyjs/mdb
132
134
  - 🔐 [用户认证](./docs/guides/authentication.md) - 使用 @linyjs/auth
133
135
  - 🛡️ [权限管理](./docs/guides/permissions.md) - 使用 @linyjs/permission
@@ -41,11 +41,11 @@ export const myModule: IModule = {
41
41
  服务定义的通用接口。
42
42
 
43
43
  ```typescript
44
- interface IServiceDef {
44
+ interface IServiceDef<S extends IService = IService, M extends IServiceMetadata = IServiceMetadata> {
45
45
  serviceTag: string;
46
- serviceImpl: any;
47
- dependencies?: string[];
48
- meta: ServiceMetadata;
46
+ serviceImpl: IServiceMaker<S>; // class 或工厂函数
47
+ dependencies?: string[]; // 支持 'serviceTag' 或 'moduleName.serviceTag'
48
+ meta?: M;
49
49
  }
50
50
  ```
51
51
 
@@ -53,10 +53,12 @@ interface IServiceDef {
53
53
 
54
54
  | 字段 | 类型 | 必填 | 说明 |
55
55
  |------|------|------|------|
56
- | `serviceTag` | string | ✅ | 服务的唯一标签 |
57
- | `serviceImpl` | class | ✅ | 服务实现类 |
58
- | `dependencies` | string[] | ❌ | 依赖的其他服务 |
59
- | `meta` | ServiceMetadata | ✅ | 元数据(包含 usageType) |
56
+ | `serviceTag` | string | ✅ | 服务的唯一标签(模块内唯一) |
57
+ | `serviceImpl` | class \| function | ✅ | 服务实现,可以是类或工厂函数 |
58
+ | `dependencies` | string[] | ❌ | 依赖的其他服务,支持模块内和跨模块引用 |
59
+ | `meta` | ServiceMetadata | ✅ | 元数据(包含 usageType |
60
+
61
+ > ⚠️ **构造函数约定**:框架将依赖组装为 `{ serviceTag: instance }` 对象传入构造函数,构造函数**必须使用解构赋值**。详见 [依赖注入机制](../guides/dependency-injection.md#构造函数约定)。
60
62
 
61
63
  ---
62
64
 
@@ -334,6 +336,17 @@ registry.register({
334
336
 
335
337
  linyjs 框架提供了以下基础模块,插件开发者可以通过依赖注入方式使用:
336
338
 
339
+ ### 可注入服务汇总
340
+
341
+ | 依赖引用 | 接口类型 | 来源模块 | 说明 |
342
+ |----------|----------|----------|------|
343
+ | `'mdb.mongoDBService'` | `IMongoDBService` | @linyjs/mdb | MongoDB 数据库服务 |
344
+ | `'authServer.userService'` | `IUserService` | @linyjs/auth | 用户管理服务 |
345
+ | `'authServer.initService'` | - | @linyjs/auth | 系统初始化服务 |
346
+ | `'permissionServer.permissionService'` | `IPermissionService` | @linyjs/permission | 权限检查服务 |
347
+
348
+ > 💡 使用 `@linyjs/shared-module-interface` 包获取这些接口的 TypeScript 类型定义,详见 [shared-module-interface 指南](../guides/shared-module-interface.md)。
349
+
337
350
  ### 数据库模块
338
351
  - **@linyjs/mdb** - MongoDB 数据库服务
339
352
  - 提供数据库连接、CRUD 操作、索引管理等功能
@@ -349,8 +362,78 @@ linyjs 框架提供了以下基础模块,插件开发者可以通过依赖注
349
362
  - 提供基于角色的访问控制(RBAC)
350
363
  - 详见:[权限管理指南](../guides/permissions.md)
351
364
 
365
+ ## 依赖注入接口
366
+
367
+ ### IService / IServiceMaker
368
+
369
+ 服务基础类型和实现类型定义:
370
+
371
+ ```typescript
372
+ // 所有服务的基础类型
373
+ type IService = object
374
+
375
+ // 服务类构造器
376
+ type IServiceConstructor<S> = new (...args: any[]) => S
377
+
378
+ // 服务工厂函数
379
+ type IServiceFactory<S> = (...args: any[]) => S
380
+
381
+ // 服务实现(类或工厂函数)
382
+ type IServiceMaker<S> = IServiceConstructor<S> | IServiceFactory<S>
383
+ ```
384
+
385
+ ### 依赖引用格式
386
+
387
+ `IServiceDef.dependencies` 中的字符串支持两种格式:
388
+
389
+ | 格式 | 示例 | 说明 |
390
+ |------|------|------|
391
+ | 模块内引用 | `'myService'` | 从当前模块已实例化的服务中查找 |
392
+ | 跨模块引用 | `'mdb.mongoDBService'` | 格式为 `moduleName.serviceTag`,从指定模块查找 |
393
+
394
+ > 📖 完整的依赖注入机制说明,请阅读 [依赖注入机制指南](../guides/dependency-injection.md)。
395
+
396
+ ### IMongoDBService
397
+
398
+ 由 @linyjs/mdb 模块实现,通过 `'mdb.mongoDBService'` 注入:
399
+
400
+ ```typescript
401
+ interface IMongoDBService {
402
+ readonly ObjectId: typeof ObjectId;
403
+ getDb(): Db;
404
+ getCollection<T>(name: string): Collection<T>;
405
+ isConnected(): boolean;
406
+ close(): Promise<void>;
407
+ }
408
+ ```
409
+
410
+ ### IUserService
411
+
412
+ 由 @linyjs/auth 模块实现,通过 `'authServer.userService'` 注入:
413
+
414
+ ```typescript
415
+ interface IUserService {
416
+ getAllUsers(): Promise<ISafeUser[]>;
417
+ updateUserRoles(userId: string, roles: string[]): Promise<ISafeUser | null>;
418
+ }
419
+ ```
420
+
421
+ ### IPermissionService
422
+
423
+ 由 @linyjs/permission 模块实现,通过 `'permissionServer.permissionService'` 注入:
424
+
425
+ ```typescript
426
+ interface IPermissionService {
427
+ check(user: IPermissionUser | null, permission: PermissionString, context?: Record<string, any>): Promise<IPermissionCheckResult>;
428
+ registerPolicy(policy: IPermissionPolicy): void;
429
+ checkMany(user: IPermissionUser | null, permissions: PermissionString[], context?: Record<string, any>): Promise<Record<PermissionString, IPermissionCheckResult>>;
430
+ }
431
+ ```
432
+
352
433
  ## 相关文档
353
434
 
435
+ - 📖 [依赖注入机制](../guides/dependency-injection.md) — DI 完整说明
436
+ - 📦 [shared-module-interface 指南](../guides/shared-module-interface.md) — 类型定义包
354
437
  - 📖 [服务端模块开发](../guides/server-module.md)
355
438
  - 💻 [客户端模块开发](../guides/client-module.md)
356
439
  - 🎨 [UI 扩展插槽](../guides/ui-slots.md)
@@ -35,7 +35,7 @@ handler: async (params, ctx) => {
35
35
  handler: async (params, ctx) => {
36
36
  try {
37
37
  // 输入验证错误
38
- if (!params.body.email) {
38
+ if (!params.email) {
39
39
  return {
40
40
  status: 400,
41
41
  data: { error: 'Email is required' }
@@ -43,7 +43,7 @@ handler: async (params, ctx) => {
43
43
  }
44
44
 
45
45
  // 业务逻辑错误
46
- const user = await findUser(params.body.email);
46
+ const user = await findUser(params.email);
47
47
  if (!user) {
48
48
  return {
49
49
  status: 404,
@@ -92,7 +92,7 @@ class AuthorizationError extends Error {
92
92
  // 在处理器中使用
93
93
  handler: async (params, ctx) => {
94
94
  try {
95
- if (!isValidEmail(params.body.email)) {
95
+ if (!isValidEmail(params.email)) {
96
96
  throw new ValidationError('Invalid email format', 'email');
97
97
  }
98
98
 
@@ -16,7 +16,7 @@
16
16
  ```typescript
17
17
  // 严格的输入验证
18
18
  handler: async (params, ctx) => {
19
- const { email, password, age } = params.body;
19
+ const { email, password, age } = params;
20
20
 
21
21
  // 邮箱格式验证
22
22
  if (!isValidEmail(email)) {
@@ -73,7 +73,7 @@ const userSchema = Joi.object({
73
73
 
74
74
  // 在处理器中使用验证
75
75
  handler: async (params, ctx) => {
76
- const { error, value } = userSchema.validate(params.body);
76
+ const { error, value } = userSchema.validate(params);
77
77
 
78
78
  if (error) {
79
79
  return {
package/docs/faq.md CHANGED
@@ -282,7 +282,7 @@ const user = await db.collection('users').findOne({
282
282
  **A:**
283
283
  ```typescript
284
284
  handler: async (params) => {
285
- const { email } = params.body;
285
+ const { email } = params;
286
286
 
287
287
  // 验证邮箱格式
288
288
  if (!isValidEmail(email)) {
@@ -162,8 +162,8 @@ export class ArticleController implements IControllerService {
162
162
  middlewares: [],
163
163
  responseType: 'json' as const,
164
164
  handler: async (params: any) => {
165
- const page = parseInt(params.query?.page || '1');
166
- const limit = parseInt(params.query?.limit || '10');
165
+ const page = parseInt(params.page || '1');
166
+ const limit = parseInt(params.limit || '10');
167
167
  return await this.articleService.getArticles(page, limit);
168
168
  }
169
169
  },
@@ -173,7 +173,7 @@ export class ArticleController implements IControllerService {
173
173
  middlewares: [],
174
174
  responseType: 'json' as const,
175
175
  handler: async (params: any) => {
176
- const article = await this.articleService.createArticle(params.body);
176
+ const article = await this.articleService.createArticle(params);
177
177
  return { success: true, data: article };
178
178
  }
179
179
  }