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.
@@ -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 Timing(invocation: ActionInvocation, next: Next): Promise<unknown> {
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(Timing)
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
- //BuildEntrypoints({controllers: [UserController], rules: [AdminRule], httpActionGroups: {admin: 'Administration'}})
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
 
@@ -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 Timing(invocation: ActionInvocation, next: Next): Promise<unknown> {
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(Timing)
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
- //BuildEntrypoints({controllers: [UserController], rules: [AdminRule], httpActionGroups: {admin: 'Administration'}})
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.1",
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.1",
330
- "@lakutata/containerd": "3.0.0-beta.1",
331
- "@lakutata/core": "3.0.0-beta.1",
332
- "@lakutata/docker": "3.0.0-beta.1",
333
- "@lakutata/entrypoint": "3.0.0-beta.1",
334
- "@lakutata/i18n": "3.0.0-beta.1",
335
- "@lakutata/logger": "3.0.0-beta.1",
336
- "@lakutata/monitor": "3.0.0-beta.1",
337
- "@lakutata/mutex": "3.0.0-beta.1",
338
- "@lakutata/orm": "3.0.0-beta.1",
339
- "@lakutata/security": "3.0.0-beta.1",
340
- "@lakutata/utils": "3.0.0-beta.1"
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",