lakutata 3.0.0-beta.1 → 3.0.0-beta.2
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/doc/en/ActionPattern.md +11 -7
- package/doc/zh/ActionPattern.md +8 -7
- package/package.json +13 -13
package/doc/en/ActionPattern.md
CHANGED
|
@@ -205,7 +205,7 @@ the `middlewares` action option.
|
|
|
205
205
|
import {type ActionInvocation, Controller, type Next} from 'lakutata/com/entrypoint'
|
|
206
206
|
import {GET, UseMiddlewares} from 'lakutata/decorator/ctrl'
|
|
207
207
|
|
|
208
|
-
async function
|
|
208
|
+
async function timing(invocation: ActionInvocation, next: Next): Promise<unknown> {
|
|
209
209
|
const started: number = Date.now()
|
|
210
210
|
try {
|
|
211
211
|
return await next()
|
|
@@ -214,7 +214,7 @@ async function Timing(invocation: ActionInvocation, next: Next): Promise<unknown
|
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
@UseMiddlewares(
|
|
217
|
+
@UseMiddlewares(timing)
|
|
218
218
|
class HealthController extends Controller {
|
|
219
219
|
@GET('/health')
|
|
220
220
|
public async health(): Promise<string> {
|
|
@@ -248,7 +248,7 @@ class UserController extends Controller {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
//
|
|
251
|
+
//buildEntrypoints({controllers: [UserController], rules: [AdminRule], httpActionGroups: {admin: 'Administration'}})
|
|
252
252
|
```
|
|
253
253
|
|
|
254
254
|
The groups of an action must be declared in `httpActionGroups`, `cliActionGroups` or `serviceActionGroups` of
|
|
@@ -287,7 +287,11 @@ launches once its server listens. To move it to `expressHTTPEntrypoint`:
|
|
|
287
287
|
- the `{errno, errMsg, data}` envelope is `jsonEnvelope()`. The applications of 2.x usually answered the errors of the
|
|
288
288
|
actions with 200 and the errors of their express middlewares (`next(error)`: an authenticator's 401) with their
|
|
289
289
|
status: `jsonEnvelope({actionErrorStatus: 200})` does the same — `errorStatus: 200` would answer the 401 with 200 too,
|
|
290
|
-
which the clients redirecting to the login page on a 401 would miss
|
|
290
|
+
which the clients redirecting to the login page on a 401 would miss;
|
|
291
|
+
- the other fields of the envelope of the application (`timestamp`, `nonce`, a request id) are given by its `extra`
|
|
292
|
+
option, called for each response, results and errors: `jsonEnvelope({actionErrorStatus: 200, extra: () =>
|
|
293
|
+
({timestamp: Date.now()})})`. They are added after `errno`, `errMsg` and `data`, which they never replace — no
|
|
294
|
+
responder of its own is needed to keep them.
|
|
291
295
|
|
|
292
296
|
```typescript
|
|
293
297
|
import {buildEntrypoints} from 'lakutata/com/entrypoint'
|
|
@@ -310,13 +314,13 @@ export const entrypoint = buildEntrypoints({
|
|
|
310
314
|
//The authenticator of the requests: its errors keep their status (401)
|
|
311
315
|
app.use((request: Request, _response: Response, next: NextFunction): void => request.headers.authorization ? next() : next(new Unauthorized('Not logged in')))
|
|
312
316
|
},
|
|
313
|
-
//The errors of the actions answered with 200 in the envelope, as in 2.x
|
|
314
|
-
respond: jsonEnvelope({actionErrorStatus: 200})
|
|
317
|
+
//The errors of the actions answered with 200 in the envelope, as in 2.x, with its timestamp
|
|
318
|
+
respond: jsonEnvelope({actionErrorStatus: 200, extra: (): Record<string, unknown> => ({timestamp: Date.now()})})
|
|
315
319
|
})
|
|
316
320
|
})
|
|
317
321
|
```
|
|
318
322
|
|
|
319
|
-
`fastifyHTTPEntrypoint` takes the same options (`fastifyJSONEnvelope({actionErrorStatus: 200})`, the authenticator
|
|
323
|
+
`fastifyHTTPEntrypoint` takes the same options (`fastifyJSONEnvelope({actionErrorStatus: 200, extra})`, the authenticator
|
|
320
324
|
being a hook of fastify). A responder of its own receives the origin of each error as the fourth argument of its
|
|
321
325
|
`error` (`'action'` or `'request'`).
|
|
322
326
|
|
package/doc/zh/ActionPattern.md
CHANGED
|
@@ -171,7 +171,7 @@ class UserController extends Controller {
|
|
|
171
171
|
import {type ActionInvocation, Controller, type Next} from 'lakutata/com/entrypoint'
|
|
172
172
|
import {GET, UseMiddlewares} from 'lakutata/decorator/ctrl'
|
|
173
173
|
|
|
174
|
-
async function
|
|
174
|
+
async function timing(invocation: ActionInvocation, next: Next): Promise<unknown> {
|
|
175
175
|
const started: number = Date.now()
|
|
176
176
|
try {
|
|
177
177
|
return await next()
|
|
@@ -180,7 +180,7 @@ async function Timing(invocation: ActionInvocation, next: Next): Promise<unknown
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
@UseMiddlewares(
|
|
183
|
+
@UseMiddlewares(timing)
|
|
184
184
|
class HealthController extends Controller {
|
|
185
185
|
@GET('/health')
|
|
186
186
|
public async health(): Promise<string> {
|
|
@@ -212,7 +212,7 @@ class UserController extends Controller {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
//
|
|
215
|
+
//buildEntrypoints({controllers: [UserController], rules: [AdminRule], httpActionGroups: {admin: 'Administration'}})
|
|
216
216
|
```
|
|
217
217
|
|
|
218
218
|
动作的分组必须在 `buildEntrypoints` 的 `httpActionGroups`、`cliActionGroups` 或 `serviceActionGroups` 中声明。`shutdownTimeout`(默认 30000 毫秒)是入口停止时留给正在处理的请求的时间。
|
|
@@ -240,7 +240,8 @@ class UserController extends Controller {
|
|
|
240
240
|
|
|
241
241
|
- 应用自己的中间件和路由(CORS、压缩、健康检查、Authenticator、Web UI)放进 `before` 钩子,钩子里用 `module.getObject()` 获取对象;请求体解析用 `body` 选项(`{limit: '100mb'}`);服务器的 `keepAliveTimeout`/`headersTimeout` 用 `server` 选项;
|
|
242
242
|
- 从请求构造动作输入(查询参数、请求体、会话中的值)用 `input` 选项;
|
|
243
|
-
- `{errno, errMsg, data}` 封套用 `jsonEnvelope()`。2.x 的应用通常对动作的错误返回 200,而对 Express 中间件的错误(`next(error)`,比如 Authenticator 的 401)使用错误自带的状态码:`jsonEnvelope({actionErrorStatus: 200})` 的行为与此相同。如果用 `errorStatus: 200`,401 也会变成 200,按 401
|
|
243
|
+
- `{errno, errMsg, data}` 封套用 `jsonEnvelope()`。2.x 的应用通常对动作的错误返回 200,而对 Express 中间件的错误(`next(error)`,比如 Authenticator 的 401)使用错误自带的状态码:`jsonEnvelope({actionErrorStatus: 200})` 的行为与此相同。如果用 `errorStatus: 200`,401 也会变成 200,按 401 跳转登录页的前端就会失效;
|
|
244
|
+
- 应用封套里的其他字段(`timestamp`、`nonce`、请求 ID)用 `extra` 选项给出。它在每次响应时调用,成功和错误的响应都会带上这些字段:`jsonEnvelope({actionErrorStatus: 200, extra: () => ({timestamp: Date.now()})})`。这些字段排在 `errno`、`errMsg`、`data` 之后,不会覆盖这三个字段,因此不需要为了保留它们自己实现响应器。
|
|
244
245
|
|
|
245
246
|
```typescript
|
|
246
247
|
import {buildEntrypoints} from 'lakutata/com/entrypoint'
|
|
@@ -263,13 +264,13 @@ export const entrypoint = buildEntrypoints({
|
|
|
263
264
|
//请求的鉴权:它的错误保留自带的状态码(401)
|
|
264
265
|
app.use((request: Request, _response: Response, next: NextFunction): void => request.headers.authorization ? next() : next(new Unauthorized('Not logged in')))
|
|
265
266
|
},
|
|
266
|
-
//动作的错误在封套中以 200 返回,与 2.x
|
|
267
|
-
respond: jsonEnvelope({actionErrorStatus: 200})
|
|
267
|
+
//动作的错误在封套中以 200 返回,与 2.x 相同,并带上时间戳
|
|
268
|
+
respond: jsonEnvelope({actionErrorStatus: 200, extra: (): Record<string, unknown> => ({timestamp: Date.now()})})
|
|
268
269
|
})
|
|
269
270
|
})
|
|
270
271
|
```
|
|
271
272
|
|
|
272
|
-
`fastifyHTTPEntrypoint` 的选项相同(使用 `fastifyJSONEnvelope({actionErrorStatus: 200})`,Authenticator 写成 Fastify 的钩子)。自定义的响应器可以从 `error` 的第四个参数得到每个错误的来源(`'action'` 或 `'request'`)。
|
|
273
|
+
`fastifyHTTPEntrypoint` 的选项相同(使用 `fastifyJSONEnvelope({actionErrorStatus: 200, extra})`,Authenticator 写成 Fastify 的钩子)。自定义的响应器可以从 `error` 的第四个参数得到每个错误的来源(`'action'` 或 `'request'`)。
|
|
273
274
|
|
|
274
275
|
### 服务动作的客户端与推送事件
|
|
275
276
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lakutata",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.2",
|
|
4
4
|
"description": "An IoC-based universal application framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -326,18 +326,18 @@
|
|
|
326
326
|
"typescript"
|
|
327
327
|
],
|
|
328
328
|
"dependencies": {
|
|
329
|
-
"@lakutata/cache": "3.0.0-beta.
|
|
330
|
-
"@lakutata/containerd": "3.0.0-beta.
|
|
331
|
-
"@lakutata/core": "3.0.0-beta.
|
|
332
|
-
"@lakutata/docker": "3.0.0-beta.
|
|
333
|
-
"@lakutata/entrypoint": "3.0.0-beta.
|
|
334
|
-
"@lakutata/i18n": "3.0.0-beta.
|
|
335
|
-
"@lakutata/logger": "3.0.0-beta.
|
|
336
|
-
"@lakutata/monitor": "3.0.0-beta.
|
|
337
|
-
"@lakutata/mutex": "3.0.0-beta.
|
|
338
|
-
"@lakutata/orm": "3.0.0-beta.
|
|
339
|
-
"@lakutata/security": "3.0.0-beta.
|
|
340
|
-
"@lakutata/utils": "3.0.0-beta.
|
|
329
|
+
"@lakutata/cache": "3.0.0-beta.2",
|
|
330
|
+
"@lakutata/containerd": "3.0.0-beta.2",
|
|
331
|
+
"@lakutata/core": "3.0.0-beta.2",
|
|
332
|
+
"@lakutata/docker": "3.0.0-beta.2",
|
|
333
|
+
"@lakutata/entrypoint": "3.0.0-beta.2",
|
|
334
|
+
"@lakutata/i18n": "3.0.0-beta.2",
|
|
335
|
+
"@lakutata/logger": "3.0.0-beta.2",
|
|
336
|
+
"@lakutata/monitor": "3.0.0-beta.2",
|
|
337
|
+
"@lakutata/mutex": "3.0.0-beta.2",
|
|
338
|
+
"@lakutata/orm": "3.0.0-beta.2",
|
|
339
|
+
"@lakutata/security": "3.0.0-beta.2",
|
|
340
|
+
"@lakutata/utils": "3.0.0-beta.2"
|
|
341
341
|
},
|
|
342
342
|
"files": [
|
|
343
343
|
"dist",
|