@_tc/template-core 0.0.1-bate.57 → 0.0.1-bate.58

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/AGENT_README.md CHANGED
@@ -102,6 +102,24 @@ config/config.{env}.(js|ts) -> app.config
102
102
  model/**/*.(js|ts) -> 内置 project service 读取的项目模型配置
103
103
  ```
104
104
 
105
+ 常用后端类型:
106
+
107
+ | 类型 | 使用场景 |
108
+ | --- | --- |
109
+ | `Ctx` | Controller、middleware、router handler 的请求上下文,包含 `ctx.params` 和可选 `ctx.reqData`。 |
110
+ | `ControllerFN` | 约束 `app/controller/*.ts` 默认导出的 controller 工厂。 |
111
+ | `ServiceFN` | 约束 `app/service/*.ts` 默认导出的 service 工厂。 |
112
+ | `MiddlewareFN` | 约束 `app/middleware/*.ts` 默认导出的 middleware 工厂。 |
113
+ | `RouterFN` | 约束 `app/router/*.ts` 默认导出的路由注册函数。 |
114
+
115
+ `ctx.reqData` 是 API 请求的统一参数入口:
116
+
117
+ - `ctx.reqData.query` 来自 `ctx.query`。
118
+ - `ctx.reqData.body` 来自 `ctx.request.body`。
119
+ - `ctx.reqData.headers` 来自 `ctx.headers`。
120
+ - `ctx.reqData.data` 按 `query -> body` 合并;字段冲突时 body 覆盖 query。
121
+ - router params 不在 `reqData` 里,继续用 `ctx.params`。
122
+
105
123
  Controller 示例:
106
124
 
107
125
  ```ts
@@ -118,15 +136,15 @@ const getProductController = ((app) => {
118
136
  list = async (ctx: Ctx) => {
119
137
  this.success(ctx, {
120
138
  data: products,
121
- page: Number(ctx.request.query.page || 1),
122
- pageSize: Number(ctx.request.query.pageSize || 10),
139
+ page: Number(ctx.reqData?.data.page || 1),
140
+ pageSize: Number(ctx.reqData?.data.pageSize || 10),
123
141
  total: products.length,
124
142
  })
125
143
  }
126
144
 
127
145
  detail = async (ctx: Ctx) => {
128
146
  const item = products.find((product) => {
129
- return product.product_id === ctx.request.query.product_id
147
+ return product.product_id === ctx.reqData?.data.product_id
130
148
  })
131
149
 
132
150
  this.success(ctx, item ?? null)
@@ -140,12 +158,12 @@ export default getProductController
140
158
  Router 示例:
141
159
 
142
160
  ```ts
143
- import type { KoaApp, Router } from '@_tc/template-core'
161
+ import type { RouterFN } from '@_tc/template-core'
144
162
 
145
- export default (app: KoaApp, router: Router) => {
163
+ export default ((app, router) => {
146
164
  router.get('/api/product/list', app.controller.product.list)
147
165
  router.get('/api/product', app.controller.product.detail)
148
- }
166
+ }) satisfies RouterFN
149
167
  ```
150
168
 
151
169
  路由挂载顺序:
@@ -156,12 +174,12 @@ export default (app: KoaApp, router: Router) => {
156
174
  - 通配、兜底、重定向类路由建议设置较大的 `level`,避免抢先匹配业务 API。
157
175
 
158
176
  ```ts
159
- import type { KoaApp, Router } from '@_tc/template-core'
177
+ import type { RouterFN } from '@_tc/template-core'
160
178
 
161
- export default (app: KoaApp, router: Router) => {
179
+ export default ((app, router) => {
162
180
  router.level = 10
163
181
  router.get('/api/fallback/:id', app.controller.fallback.detail)
164
- }
182
+ }) satisfies RouterFN
165
183
  ```
166
184
 
167
185
  内置响应约定:`BaseController.success(ctx, data)` 返回 `{ data, code: 0, message: 'ok' }`。
package/README.md CHANGED
@@ -165,6 +165,49 @@ http://localhost:9000/dash?projk=demo
165
165
  | `@_tc/template-core/fe/tailwind_ui.css` | 前端全局样式入口,源码对应 `frontend/src/main.css` |
166
166
  | `@_tc/template-core/model` | model 配置类型 |
167
167
 
168
+ ### 后端类型
169
+
170
+ `@_tc/template-core` 会导出常用 Node 侧类型,业务项目写 `app/*` 文件时建议优先复用这些类型。
171
+
172
+ | 类型 | 使用场景 |
173
+ | --- | --- |
174
+ | `Ctx` | Controller、middleware、router handler 的 Koa 请求上下文类型,包含框架补充的 `ctx.params` 和可选 `ctx.reqData`。 |
175
+ | `ControllerFN` | `app/controller/*.ts` 默认导出工厂函数的约束类型,适合配合 `satisfies ControllerFN` 保留 controller 实例方法类型。 |
176
+ | `ServiceFN` | `app/service/*.ts` 默认导出工厂函数的约束类型,适合配合 `satisfies ServiceFN` 约束 service class 工厂。 |
177
+ | `MiddlewareFN` | `app/middleware/*.ts` 默认导出工厂函数的约束类型,返回标准 Koa middleware。 |
178
+ | `RouterFN` | `app/router/*.ts` 默认导出函数的约束类型,用于接收 `app` 和 `router` 并注册路由。 |
179
+
180
+ 示例:
181
+
182
+ ```ts
183
+ import { baseFn, type ControllerFN, type Ctx, type MiddlewareFN, type RouterFN, type ServiceFN } from '@_tc/template-core'
184
+
185
+ export const getDemoController = ((app) => {
186
+ const BaseController = baseFn.baseControllerFn(app)
187
+
188
+ return class DemoController extends BaseController {
189
+ list = async (ctx: Ctx) => {
190
+ this.success(ctx, ctx.reqData?.data ?? {})
191
+ }
192
+ }
193
+ }) satisfies ControllerFN
194
+
195
+ export const getDemoService = ((app) => {
196
+ return class DemoService {
197
+ readonly app = app
198
+ }
199
+ }) satisfies ServiceFN
200
+
201
+ export const demoMiddleware = ((app) => async (ctx, next) => {
202
+ app.extends.logger?.info(ctx.path)
203
+ await next()
204
+ }) satisfies MiddlewareFN
205
+
206
+ export const demoRouter = ((app, router) => {
207
+ router.get(`${app.options.apiPrefix}/demo/list`, app.controller.demo.list)
208
+ }) satisfies RouterFN
209
+ ```
210
+
168
211
  ## 样式与 Tailwind V4
169
212
 
170
213
  使用内置前端或 UI 组件时,需要引入包内样式。默认 `@_tc/template-core/fe` 的 `initApp` 会经过源码入口 `frontend/src/main.tsx` 引入 `frontend/src/main.css`;如果项目侧自定义入口、只使用 `fe/rc` 组件,或希望样式入口更明确,建议显式引入:
@@ -662,6 +705,24 @@ model/**/*.(js|ts) -> 项目模型配置
662
705
  - `app.extends.crypto`:Node 侧加密辅助方法,支持 base64url 编解码、HMAC 签名、签名 payload 和常量时间比较。
663
706
  - `app.extends.db`:默认 SQLite 框架数据库,提供 `getDBData/setDBData` 等通用数据方法。
664
707
 
708
+ API controller 可以通过 `ctx.reqData` 读取统一请求参数:
709
+
710
+ ```ts
711
+ const { query, body, headers, data } = ctx.reqData ?? {
712
+ query: {},
713
+ body: undefined,
714
+ headers: {},
715
+ data: {},
716
+ }
717
+ ```
718
+
719
+ - `query` 来自 `ctx.query`。
720
+ - `body` 来自 `ctx.request.body`。
721
+ - `headers` 来自 `ctx.headers`。
722
+ - `data` 是便捷合并层,当前按 `query -> body` 顺序合并;字段冲突时 body 覆盖 query。
723
+
724
+ `ctx.reqData` 只在 API 请求中由内置中间件注入,类型上是可选字段。router params 不在 `reqData` 里,仍然从 `ctx.params` 获取。
725
+
665
726
  ### 数据库扩展
666
727
 
667
728
  默认 `app.extends.db` 使用 SQLite 保存数据,数据库文件位于项目根目录 `.template-core/template-core.sqlite`。可以在配置中调整路径:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@_tc/template-core",
3
- "version": "0.0.1-bate.57",
3
+ "version": "0.0.1-bate.58",
4
4
  "description": "A full-stack TypeScript admin framework powered by Koa, React, and Vite - monorepo root",
5
5
  "types": "./types/index.d.ts",
6
6
  "exports": {
@@ -64,7 +64,12 @@
64
64
  "tailwindcss": "4.2.4"
65
65
  },
66
66
  "peerDependencies": {
67
- "@types/node": ">=18.0.0",
67
+ "@types/json-schema": "7.0.15",
68
+ "@types/md5": "2.3.6",
69
+ "@types/node": "20.19.39",
70
+ "@types/nunjucks": "3.2.6",
71
+ "@types/koa-router": "7.4.9",
72
+ "@types/koa": "2.15.0",
68
73
  "@vitejs/plugin-react": "6.0.1",
69
74
  "clsx": "^2.1.0",
70
75
  "date-fns": "^3.6.0",