@taicode/common-server 4.0.0-beta.3 → 4.0.0-beta.4
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/output/app/index.d.ts +13 -15
- package/output/app/index.d.ts.map +1 -1
- package/output/app/index.js +256 -18
- package/output/auth/index.d.ts +72 -0
- package/output/auth/index.d.ts.map +1 -0
- package/output/auth/index.js +176 -0
- package/output/core/assemble.d.ts +64 -0
- package/output/core/assemble.d.ts.map +1 -0
- package/output/core/assemble.js +88 -0
- package/output/core/boot/context.d.ts +89 -0
- package/output/core/boot/context.d.ts.map +1 -0
- package/output/{app → core/boot}/context.js +44 -17
- package/output/{app → core/boot}/lifecycle.d.ts +13 -15
- package/output/core/boot/lifecycle.d.ts.map +1 -0
- package/output/{app → core/boot}/lifecycle.js +15 -12
- package/output/{app → core/boot}/shutdown.d.ts +9 -6
- package/output/core/boot/shutdown.d.ts.map +1 -0
- package/output/{app → core/boot}/shutdown.js +7 -4
- package/output/core/boot/signal.d.ts +13 -0
- package/output/core/boot/signal.d.ts.map +1 -0
- package/output/{app → core/boot}/signal.js +3 -2
- package/output/core/boot/steps.d.ts +107 -0
- package/output/core/boot/steps.d.ts.map +1 -0
- package/output/core/boot/steps.js +200 -0
- package/output/core/entries.d.ts +123 -0
- package/output/core/entries.d.ts.map +1 -0
- package/output/core/entries.js +193 -0
- package/output/core/entries.test.d.ts +2 -0
- package/output/core/entries.test.d.ts.map +1 -0
- package/output/core/entries.test.js +217 -0
- package/output/core/env.d.ts +62 -0
- package/output/core/env.d.ts.map +1 -0
- package/output/core/env.js +96 -0
- package/output/{app → core}/env.test.d.ts.map +1 -1
- package/output/core/env.test.js +105 -0
- package/output/core/modules/auth-provider/index.d.ts +10 -0
- package/output/core/modules/auth-provider/index.d.ts.map +1 -0
- package/output/core/modules/auth-provider/index.js +9 -0
- package/output/core/modules/auth-provider/types.d.ts +71 -0
- package/output/core/modules/auth-provider/types.d.ts.map +1 -0
- package/output/core/modules/context/index.d.ts +18 -0
- package/output/core/modules/context/index.d.ts.map +1 -0
- package/output/core/modules/context/index.js +23 -0
- package/output/core/modules/context/index.test.d.ts.map +1 -0
- package/output/core/modules/cookie/index.d.ts +21 -0
- package/output/core/modules/cookie/index.d.ts.map +1 -0
- package/output/{app/core/cookie.js → core/modules/cookie/index.js} +1 -6
- package/output/core/modules/identity/index.d.ts +4 -0
- package/output/core/modules/identity/index.d.ts.map +1 -0
- package/output/{app/core/identity.js → core/modules/identity/index.js} +1 -1
- package/output/core/modules/logging/index.d.ts +5 -0
- package/output/core/modules/logging/index.d.ts.map +1 -0
- package/output/{app/core/logging.js → core/modules/logging/index.js} +2 -2
- package/output/core/modules/openapi/index.d.ts +7 -0
- package/output/core/modules/openapi/index.d.ts.map +1 -0
- package/output/{app/core/openapi.js → core/modules/openapi/index.js} +11 -12
- package/output/core/modules/permission-operations/index.d.ts +26 -0
- package/output/core/modules/permission-operations/index.d.ts.map +1 -0
- package/output/core/modules/permission-operations/index.js +36 -0
- package/output/core/modules/permission-operations/index.test.d.ts +2 -0
- package/output/core/modules/permission-operations/index.test.d.ts.map +1 -0
- package/output/core/modules/permission-operations/index.test.js +45 -0
- package/output/{app/core/request-id.d.ts → core/modules/request-id/index.d.ts} +1 -4
- package/output/core/modules/request-id/index.d.ts.map +1 -0
- package/output/{app/core/request-id.js → core/modules/request-id/index.js} +2 -2
- package/output/core/modules/response/index.d.ts +22 -0
- package/output/core/modules/response/index.d.ts.map +1 -0
- package/output/{app/core/response.js → core/modules/response/index.js} +22 -11
- package/output/{schema/index.d.ts → core/modules/schema/builders.d.ts} +8 -1
- package/output/core/modules/schema/builders.d.ts.map +1 -0
- package/output/{schema/index.js → core/modules/schema/builders.js} +7 -4
- package/output/core/modules/schema/index.d.ts +34 -0
- package/output/core/modules/schema/index.d.ts.map +1 -0
- package/output/core/modules/schema/index.js +62 -0
- package/output/core/modules/schema/index.test.d.ts +2 -0
- package/output/core/modules/schema/index.test.d.ts.map +1 -0
- package/output/core/modules/schema/index.test.js +55 -0
- package/output/core/modules/system-routes/index.d.ts +15 -0
- package/output/core/modules/system-routes/index.d.ts.map +1 -0
- package/output/core/modules/system-routes/index.js +171 -0
- package/output/core/test-support/database.d.ts +96 -0
- package/output/core/test-support/database.d.ts.map +1 -0
- package/output/core/test-support/database.js +144 -0
- package/output/core/test-support/database.test.d.ts +2 -0
- package/output/core/test-support/database.test.d.ts.map +1 -0
- package/output/core/test-support/database.test.js +110 -0
- package/output/core/test-support/environment.d.ts +33 -0
- package/output/core/test-support/environment.d.ts.map +1 -0
- package/output/core/test-support/environment.js +42 -0
- package/output/core/test-support/test-server.d.ts +94 -0
- package/output/core/test-support/test-server.d.ts.map +1 -0
- package/output/core/test-support/test-server.js +60 -0
- package/output/core/test-support/test-server.test.d.ts +2 -0
- package/output/core/test-support/test-server.test.d.ts.map +1 -0
- package/output/core/test-support/test-server.test.js +162 -0
- package/output/{app → core}/type-augment.d.ts +2 -2
- package/output/core/type-augment.d.ts.map +1 -0
- package/output/{app → core}/types.d.ts +153 -66
- package/output/core/types.d.ts.map +1 -0
- package/output/cors/index.d.ts +3 -0
- package/output/cors/index.d.ts.map +1 -0
- package/output/cors/index.js +27 -0
- package/output/index.d.ts +8 -4
- package/output/index.d.ts.map +1 -1
- package/output/index.js +24 -5
- package/output/rate-limit/index.d.ts +23 -0
- package/output/rate-limit/index.d.ts.map +1 -0
- package/output/rate-limit/index.js +42 -0
- package/output/{rate-limiter/rate-limiter.d.ts → rate-limit/limiter.d.ts} +1 -1
- package/output/rate-limit/limiter.d.ts.map +1 -0
- package/output/rate-limit/memory-store.d.ts.map +1 -0
- package/output/rate-limit/redis-store.d.ts.map +1 -0
- package/output/rate-limit/redis-store.test.d.ts.map +1 -0
- package/output/{rate-limiter → rate-limit}/redis-store.test.js +2 -2
- package/output/{rate-limiter → rate-limit}/types.d.ts +0 -1
- package/output/rate-limit/types.d.ts.map +1 -0
- package/output/rate-limit/types.js +1 -0
- package/output/{redis-cache/redis-cache.d.ts → redis/cache.d.ts} +1 -1
- package/output/redis/cache.d.ts.map +1 -0
- package/output/redis/cache.test.d.ts +2 -0
- package/output/redis/cache.test.d.ts.map +1 -0
- package/output/{redis-cache/redis-cache.test.js → redis/cache.test.js} +1 -1
- package/output/{app/redis.d.ts → redis/index.d.ts} +7 -6
- package/output/redis/index.d.ts.map +1 -0
- package/output/{app/redis.js → redis/index.js} +10 -4
- package/output/redis/index.test.d.ts +2 -0
- package/output/{context → redis}/index.test.d.ts.map +1 -1
- package/output/redis/index.test.js +55 -0
- package/output/redis-queue/index.js +1 -1
- package/output/redis-queue/test-helpers.d.ts +1 -1
- package/output/redis-queue/test-helpers.js +1 -1
- package/output/redis-queue/types.d.ts +3 -12
- package/output/redis-queue/types.d.ts.map +1 -1
- package/package.json +16 -15
- package/LICENSE +0 -21
- package/output/app/auth.test.d.ts +0 -2
- package/output/app/auth.test.d.ts.map +0 -1
- package/output/app/auth.test.js +0 -148
- package/output/app/boot.d.ts +0 -44
- package/output/app/boot.d.ts.map +0 -1
- package/output/app/boot.js +0 -158
- package/output/app/config.test.d.ts +0 -2
- package/output/app/config.test.d.ts.map +0 -1
- package/output/app/config.test.js +0 -132
- package/output/app/context.d.ts +0 -74
- package/output/app/context.d.ts.map +0 -1
- package/output/app/core/cookie.d.ts +0 -25
- package/output/app/core/cookie.d.ts.map +0 -1
- package/output/app/core/identity.d.ts +0 -12
- package/output/app/core/identity.d.ts.map +0 -1
- package/output/app/core/index.d.ts +0 -44
- package/output/app/core/index.d.ts.map +0 -1
- package/output/app/core/index.js +0 -57
- package/output/app/core/logging.d.ts +0 -13
- package/output/app/core/logging.d.ts.map +0 -1
- package/output/app/core/openapi.d.ts +0 -17
- package/output/app/core/openapi.d.ts.map +0 -1
- package/output/app/core/request-id.d.ts.map +0 -1
- package/output/app/core/response.d.ts +0 -41
- package/output/app/core/response.d.ts.map +0 -1
- package/output/app/define-server.negative-cases.d.ts +0 -40
- package/output/app/define-server.negative-cases.d.ts.map +0 -1
- package/output/app/define-server.negative-cases.js +0 -268
- package/output/app/define-server.test.d.ts +0 -2
- package/output/app/define-server.test.d.ts.map +0 -1
- package/output/app/define-server.test.js +0 -97
- package/output/app/entries.d.ts +0 -31
- package/output/app/entries.d.ts.map +0 -1
- package/output/app/entries.js +0 -66
- package/output/app/env.d.ts +0 -59
- package/output/app/env.d.ts.map +0 -1
- package/output/app/env.js +0 -66
- package/output/app/env.test.js +0 -124
- package/output/app/error-contract.test.d.ts +0 -2
- package/output/app/error-contract.test.d.ts.map +0 -1
- package/output/app/error-contract.test.js +0 -227
- package/output/app/errors.d.ts +0 -20
- package/output/app/errors.d.ts.map +0 -1
- package/output/app/errors.js +0 -51
- package/output/app/generate-openapi.test.d.ts +0 -2
- package/output/app/generate-openapi.test.d.ts.map +0 -1
- package/output/app/generate-openapi.test.js +0 -123
- package/output/app/lifecycle-logging.test.d.ts +0 -2
- package/output/app/lifecycle-logging.test.d.ts.map +0 -1
- package/output/app/lifecycle-logging.test.js +0 -175
- package/output/app/lifecycle.d.ts.map +0 -1
- package/output/app/lifecycle.test.d.ts +0 -2
- package/output/app/lifecycle.test.d.ts.map +0 -1
- package/output/app/lifecycle.test.js +0 -153
- package/output/app/middleware/auth.d.ts +0 -71
- package/output/app/middleware/auth.d.ts.map +0 -1
- package/output/app/middleware/auth.js +0 -190
- package/output/app/middleware/context.d.ts +0 -13
- package/output/app/middleware/context.d.ts.map +0 -1
- package/output/app/middleware/context.js +0 -15
- package/output/app/middleware/cors.d.ts +0 -14
- package/output/app/middleware/cors.d.ts.map +0 -1
- package/output/app/middleware/cors.js +0 -30
- package/output/app/middleware/index.d.ts +0 -17
- package/output/app/middleware/index.d.ts.map +0 -1
- package/output/app/middleware/index.js +0 -16
- package/output/app/middleware/rate-limit.d.ts +0 -24
- package/output/app/middleware/rate-limit.d.ts.map +0 -1
- package/output/app/middleware/rate-limit.js +0 -46
- package/output/app/middleware-order.test.d.ts +0 -2
- package/output/app/middleware-order.test.d.ts.map +0 -1
- package/output/app/middleware-order.test.js +0 -149
- package/output/app/permission-operations.d.ts +0 -48
- package/output/app/permission-operations.d.ts.map +0 -1
- package/output/app/permission-operations.js +0 -77
- package/output/app/permission-operations.test.d.ts +0 -2
- package/output/app/permission-operations.test.d.ts.map +0 -1
- package/output/app/permission-operations.test.js +0 -72
- package/output/app/permission-registration.test.d.ts +0 -2
- package/output/app/permission-registration.test.d.ts.map +0 -1
- package/output/app/permission-registration.test.js +0 -138
- package/output/app/redis.d.ts.map +0 -1
- package/output/app/registered-operations.test.d.ts +0 -2
- package/output/app/registered-operations.test.d.ts.map +0 -1
- package/output/app/registered-operations.test.js +0 -57
- package/output/app/request-id.test.d.ts +0 -2
- package/output/app/request-id.test.d.ts.map +0 -1
- package/output/app/request-id.test.js +0 -130
- package/output/app/resources.test.d.ts +0 -2
- package/output/app/resources.test.d.ts.map +0 -1
- package/output/app/resources.test.js +0 -222
- package/output/app/shutdown.d.ts.map +0 -1
- package/output/app/shutdown.test.d.ts +0 -2
- package/output/app/shutdown.test.d.ts.map +0 -1
- package/output/app/shutdown.test.js +0 -210
- package/output/app/signal.d.ts +0 -12
- package/output/app/signal.d.ts.map +0 -1
- package/output/app/smoke.test.d.ts +0 -2
- package/output/app/smoke.test.d.ts.map +0 -1
- package/output/app/smoke.test.js +0 -210
- package/output/app/test-support.d.ts +0 -21
- package/output/app/test-support.d.ts.map +0 -1
- package/output/app/test-support.js +0 -24
- package/output/app/type-augment.d.ts.map +0 -1
- package/output/app/types.d.ts.map +0 -1
- package/output/context/index.d.ts +0 -6
- package/output/context/index.d.ts.map +0 -1
- package/output/context/index.js +0 -14
- package/output/rate-limiter/index.d.ts +0 -5
- package/output/rate-limiter/index.d.ts.map +0 -1
- package/output/rate-limiter/index.js +0 -4
- package/output/rate-limiter/memory-store.d.ts.map +0 -1
- package/output/rate-limiter/rate-limiter.d.ts.map +0 -1
- package/output/rate-limiter/redis-store.d.ts.map +0 -1
- package/output/rate-limiter/redis-store.test.d.ts.map +0 -1
- package/output/rate-limiter/types.d.ts.map +0 -1
- package/output/redis-cache/index.d.ts +0 -4
- package/output/redis-cache/index.d.ts.map +0 -1
- package/output/redis-cache/index.js +0 -1
- package/output/redis-cache/redis-cache.d.ts.map +0 -1
- package/output/redis-cache/redis-cache.test.d.ts +0 -2
- package/output/redis-cache/redis-cache.test.d.ts.map +0 -1
- package/output/schema/index.d.ts.map +0 -1
- /package/output/{app → core}/env.test.d.ts +0 -0
- /package/output/{rate-limiter → core/modules/auth-provider}/types.js +0 -0
- /package/output/{context → core/modules/context}/index.test.d.ts +0 -0
- /package/output/{context → core/modules/context}/index.test.js +0 -0
- /package/output/{app → core}/type-augment.js +0 -0
- /package/output/{app → core}/types.js +0 -0
- /package/output/{rate-limiter/rate-limiter.js → rate-limit/limiter.js} +0 -0
- /package/output/{rate-limiter → rate-limit}/memory-store.d.ts +0 -0
- /package/output/{rate-limiter → rate-limit}/memory-store.js +0 -0
- /package/output/{rate-limiter → rate-limit}/redis-store.d.ts +0 -0
- /package/output/{rate-limiter → rate-limit}/redis-store.js +0 -0
- /package/output/{rate-limiter → rate-limit}/redis-store.test.d.ts +0 -0
- /package/output/{redis-cache/redis-cache.js → redis/cache.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../source/core/assemble.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,GAAG,eAAe,CAM7D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;AAED,gBAAgB;AAChB,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,QAAQ,EAAE,WAAW,CAAA;IACrB,GAAG,EAAE,SAAS,CAAA;IACd,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,eAAe,CAAA;IACvC,2DAA2D;IAC3D,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CACrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC,GAAG,IAAI,CAIrH;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC,uBAAuB,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlI;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWxG"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import Fastify from 'fastify';
|
|
2
|
+
import { registerCookie } from './modules/cookie/index.js';
|
|
3
|
+
import { registerRequestContext } from './modules/context/index.js';
|
|
4
|
+
import { attachServerIdentity } from './modules/identity/index.js';
|
|
5
|
+
import { createLoggerOptions } from './modules/logging/index.js';
|
|
6
|
+
import { registerOpenApi } from './modules/openapi/index.js';
|
|
7
|
+
import { createRequestIdOptions, registerRequestId } from './modules/request-id/index.js';
|
|
8
|
+
import { registerResponse } from './modules/response/index.js';
|
|
9
|
+
import { installRouteSchemaGuard, registerSchema } from './modules/schema/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* core 步骤 `createFastify`(`prepare`)。
|
|
12
|
+
*
|
|
13
|
+
* **总是**建 pino logger(level = `LOG_LEVEL`,默认 `info`) + 内置 `requestId`(入站 `x-request-id`
|
|
14
|
+
* 复用 / `randomUUID`,日志字段 `requestId`)。`trustProxy: true` 与四家现状一致。
|
|
15
|
+
*
|
|
16
|
+
* 固定装配,**不从包对外导出**:对外入口只有 `defineServer` / `startServer` / `generateOpenApi`。
|
|
17
|
+
*/
|
|
18
|
+
export function createFastify(env) {
|
|
19
|
+
return Fastify({
|
|
20
|
+
trustProxy: true,
|
|
21
|
+
logger: createLoggerOptions(env),
|
|
22
|
+
...createRequestIdOptions(),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 出文档用的**最小实例**(`generateOpenApi` 专用)。
|
|
27
|
+
*
|
|
28
|
+
* 没有 logger、没有 `requestId`、没有 `trustProxy`——这些只在**有请求**时才有意义,
|
|
29
|
+
* 而构建期一条请求都不会发。`logger: false` 下 `app.log` 仍是 `abstract-logging` 的
|
|
30
|
+
* 空实现,满足 `LoggerLike`,因此下游单元拿到的 `ctx.log` 调用不会炸,也不会产生输出。
|
|
31
|
+
*/
|
|
32
|
+
export function createDocumentFastify() {
|
|
33
|
+
return Fastify({ logger: false });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* **schema 契约**(固定序,不可替换):`identity` → `schema`(zod compiler)→ 路由契约守卫。
|
|
37
|
+
*
|
|
38
|
+
* 两个入口都必须有它:
|
|
39
|
+
* - `startServer` 要让 zod 真的校验/序列化请求,并让「路由缺 `schema`」在注册处就失败;
|
|
40
|
+
* - `generateOpenApi` 要把 zod 转成 JSON Schema 出文档,也要同一个守卫——**文档就是权限目录**,
|
|
41
|
+
* 构建期放过的路由会在线上变成「接口永远判不过」。
|
|
42
|
+
*
|
|
43
|
+
* 单独成函数是为了让「运行期 core」与「文档 core」两条装配路径共用同一段契约,
|
|
44
|
+
* 而不用把整段运行期能力拖进出文档路径。
|
|
45
|
+
*/
|
|
46
|
+
export function registerSchemaContract(app, options) {
|
|
47
|
+
attachServerIdentity(app, options.identity);
|
|
48
|
+
registerSchema(app); // schema → zod compiler
|
|
49
|
+
installRouteSchemaGuard(app); // 强制所有路由声明 schema(含 operationId / summary / description / tags)
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* **文档 core**(`generateOpenApi` 专用):schema 契约 + swagger。
|
|
53
|
+
*
|
|
54
|
+
* 只有这三件事与「把 zod schema 转成 OpenAPI 文档」有关:身份(`info.title` /
|
|
55
|
+
* `info.version`)、zod compiler(转换前得能读懂 zod)、守卫(不让文档缺条目)、swagger(转换器)。
|
|
56
|
+
* `requestContext` / `cookie` / `response` / `requestId` 全部**不装**——它们只影响
|
|
57
|
+
* 请求怎么被处理,而构建期一条请求都不会发。
|
|
58
|
+
*/
|
|
59
|
+
export async function registerDocumentCore(app, options) {
|
|
60
|
+
registerSchemaContract(app, options);
|
|
61
|
+
// await:确定性冲刷插件队列,保证 swagger 的 root `onRoute` 钩子在路由注册之前就位
|
|
62
|
+
await registerOpenApi(app, {
|
|
63
|
+
title: options.identity.title,
|
|
64
|
+
version: options.identity.version,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* core 装配(固定序,不可替换):`identity` → `schema`(+ 路由契约守卫)→ `requestContext`
|
|
69
|
+
* → `cookie` → `response` → `openapi` → `requestId` 回吐。
|
|
70
|
+
*
|
|
71
|
+
* 全部为框架内置能力,**不暴露选项面**;`request.ctx` 的装配也在这一步完成(`type-augment` 的
|
|
72
|
+
* 类型承诺因此总有运行期对应物)。**构造期不读配置**(`cookie` 的 domain 在请求期惰性读取),
|
|
73
|
+
* 故出 spec 路径(`readConfig` 不可用)不会触发。
|
|
74
|
+
*
|
|
75
|
+
* 这里**不建路由注册表**:权限目录直接由 `app.swagger()` 生成的文档派生(OpenAPI 是唯一来源)。
|
|
76
|
+
*/
|
|
77
|
+
export async function registerCore(app, options) {
|
|
78
|
+
registerSchemaContract(app, options);
|
|
79
|
+
registerRequestContext(app); // request.ctx(type-augment 承诺的运行期对应物)
|
|
80
|
+
registerCookie(app, { env: options.env, readConfig: options.readConfig });
|
|
81
|
+
registerResponse(app, { classifyResourceError: options.classifyResourceError });
|
|
82
|
+
// await:确定性冲刷插件队列,保证 swagger 的 root `onRoute` 钩子在路由注册之前就位
|
|
83
|
+
await registerOpenApi(app, {
|
|
84
|
+
title: options.identity.title,
|
|
85
|
+
version: options.identity.version,
|
|
86
|
+
});
|
|
87
|
+
registerRequestId(app); // 响应回吐 x-request-id
|
|
88
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Disposer } from '@taicode/common-base';
|
|
2
|
+
import type { ConfigEnv } from '../env.js';
|
|
3
|
+
import type { AppInstance, ClientsContext, ClientsView, ConfigContext, ErrorClassifier, LoggerLike, MiddlewareContext, ResourcesContext, ResourcesView, RouterContext, ServiceContext } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* 分阶段 ctx 的运行时构造(N1 §2)。
|
|
6
|
+
*
|
|
7
|
+
* 每个槽位拿到的是**字段最小集合**的普通对象;`config` 用 getter 暴露,出 spec 路径
|
|
8
|
+
* (`generateOpenApi` 不跑 `config` 槽位)读到它时抛 `SystemError('CONFIG_UNAVAILABLE')`
|
|
9
|
+
* —— 让「构造期不得读配置」有运行期护栏,而不仅是文档规则。
|
|
10
|
+
*/
|
|
11
|
+
/** 运行时镜像 `Live<T>`:剔除值为 `false` 的键(编译期静态关闭) */
|
|
12
|
+
export declare function liveResources(resources: object): Record<string, unknown>;
|
|
13
|
+
/** 客户端包的运行时镜像(口径与 `liveResources` 完全一致,另立一名只为调用处可读) */
|
|
14
|
+
export declare function liveClients(clients: object): Record<string, unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* `config` 槽位的**读取能力**(不是容器)。
|
|
17
|
+
*
|
|
18
|
+
* 装配期各单元需要的是「能不能读、读到什么」,不是「一个有 `current` 字段的箱子」——
|
|
19
|
+
* 后者把**写入**也一并交给了每个拿到 `BootContext` 的步骤,绕开 `buildConfig` 就能改配置。
|
|
20
|
+
* 因此这里只暴露读:`available`(有没有产出)+ `read()`(读,未产出即抛)。
|
|
21
|
+
*
|
|
22
|
+
* 写入通道是**私有 Symbol**(本文件内、不导出):调用方连键名都写不出来,只能通过
|
|
23
|
+
* `provideConfig()` 写,而它只被 `buildConfig` 调用。
|
|
24
|
+
*/
|
|
25
|
+
export interface ConfigAccess<C> {
|
|
26
|
+
/** `config` 槽位是否已产出(出 spec 路径恒为 `false`) */
|
|
27
|
+
readonly available: boolean;
|
|
28
|
+
/** 读配置;未产出时抛 `SystemError('CONFIG_UNAVAILABLE')` */
|
|
29
|
+
read(): Awaited<C>;
|
|
30
|
+
}
|
|
31
|
+
export declare function createConfigAccess<C>(): ConfigAccess<C>;
|
|
32
|
+
/** 写入 `config` 产物(唯一的写入口:由 `buildConfig` 调用,不在 `BootContext` 上暴露) */
|
|
33
|
+
export declare function provideConfig<C>(access: ConfigAccess<C>, value: Awaited<C>): void;
|
|
34
|
+
/** 按**已知键**从配置值里取字段(框架内置单元消费配置的单一入口;不做形状校验) */
|
|
35
|
+
export declare function readConfigKey(config: unknown, key: string): unknown;
|
|
36
|
+
/** `resources(ctx)` 入参 */
|
|
37
|
+
export interface ResourcesContextParams {
|
|
38
|
+
env: ConfigEnv;
|
|
39
|
+
log: LoggerLike;
|
|
40
|
+
disposer: Disposer;
|
|
41
|
+
/** 收集器:`buildResources` 注入,把各资源注册的分类器按注册顺序收起来 */
|
|
42
|
+
registerClassifyError: (classifier: ErrorClassifier) => void;
|
|
43
|
+
}
|
|
44
|
+
export declare function createResourcesContext(params: ResourcesContextParams): ResourcesContext;
|
|
45
|
+
/** `config(ctx)` 入参 */
|
|
46
|
+
export interface ConfigContextParams<R> {
|
|
47
|
+
env: ConfigEnv;
|
|
48
|
+
log: LoggerLike;
|
|
49
|
+
disposer: Disposer;
|
|
50
|
+
resources: ResourcesView<R>;
|
|
51
|
+
}
|
|
52
|
+
export declare function createConfigContext<R>(params: ConfigContextParams<R>): ConfigContext<R>;
|
|
53
|
+
/** `clients(ctx)` 入参(与 `services` 同依赖集:`resources` + `config`) */
|
|
54
|
+
export interface ClientsContextParams<R, C> {
|
|
55
|
+
log: LoggerLike;
|
|
56
|
+
disposer: Disposer;
|
|
57
|
+
resources: ResourcesView<R>;
|
|
58
|
+
configAccess: ConfigAccess<C>;
|
|
59
|
+
}
|
|
60
|
+
export declare function createClientsContext<R, C>(params: ClientsContextParams<R, C>): ClientsContext<R, C>;
|
|
61
|
+
/** `services(ctx)` 入参 */
|
|
62
|
+
export interface ServiceContextParams<R, C, CL> {
|
|
63
|
+
log: LoggerLike;
|
|
64
|
+
disposer: Disposer;
|
|
65
|
+
resources: ResourcesView<R>;
|
|
66
|
+
configAccess: ConfigAccess<C>;
|
|
67
|
+
clients: ClientsView<CL>;
|
|
68
|
+
}
|
|
69
|
+
export declare function createServiceContext<R, C, CL>(params: ServiceContextParams<R, C, CL>): ServiceContext<R, C, CL>;
|
|
70
|
+
/** `middlewares(ctx)` 入参 */
|
|
71
|
+
export interface MiddlewareContextParams<C, S, CL> {
|
|
72
|
+
app: AppInstance;
|
|
73
|
+
log: LoggerLike;
|
|
74
|
+
disposer: Disposer;
|
|
75
|
+
services: Awaited<S>;
|
|
76
|
+
configAccess: ConfigAccess<C>;
|
|
77
|
+
clients: ClientsView<CL>;
|
|
78
|
+
}
|
|
79
|
+
export declare function createMiddlewareContext<C, S, CL>(params: MiddlewareContextParams<C, S, CL>): MiddlewareContext<C, S, CL>;
|
|
80
|
+
/** `routers(ctx)` 入参 */
|
|
81
|
+
export interface RouterContextParams<S, CL> {
|
|
82
|
+
app: AppInstance;
|
|
83
|
+
log: LoggerLike;
|
|
84
|
+
disposer: Disposer;
|
|
85
|
+
services: Awaited<S>;
|
|
86
|
+
clients: ClientsView<CL>;
|
|
87
|
+
}
|
|
88
|
+
export declare function createRouterContext<S, CL>(params: RouterContextParams<S, CL>): RouterContext<S, CL>;
|
|
89
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../source/core/boot/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SystemError } from '
|
|
1
|
+
import { SystemError } from '@taicode/common-base';
|
|
2
2
|
/**
|
|
3
3
|
* 分阶段 ctx 的运行时构造(N1 §2)。
|
|
4
4
|
*
|
|
@@ -16,15 +16,36 @@ export function liveResources(resources) {
|
|
|
16
16
|
}
|
|
17
17
|
return result;
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
/** 客户端包的运行时镜像(口径与 `liveResources` 完全一致,另立一名只为调用处可读) */
|
|
20
|
+
export function liveClients(clients) {
|
|
21
|
+
return liveResources(clients);
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
-
export function
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
const CONFIG_WRITE = Symbol('config.write');
|
|
24
|
+
export function createConfigAccess() {
|
|
25
|
+
let value;
|
|
26
|
+
const access = {
|
|
27
|
+
get available() {
|
|
28
|
+
return value !== undefined;
|
|
29
|
+
},
|
|
30
|
+
read() {
|
|
31
|
+
if (value === undefined) {
|
|
32
|
+
throw new SystemError('CONFIG_UNAVAILABLE', undefined, '配置尚未就绪(generateOpenApi 路径不跑 config 槽位):任何单元不得在构造期读配置');
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
},
|
|
36
|
+
[CONFIG_WRITE](next) {
|
|
37
|
+
value = next;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
return access;
|
|
41
|
+
}
|
|
42
|
+
/** 写入 `config` 产物(唯一的写入口:由 `buildConfig` 调用,不在 `BootContext` 上暴露) */
|
|
43
|
+
export function provideConfig(access, value) {
|
|
44
|
+
const write = access[CONFIG_WRITE];
|
|
45
|
+
if (write === undefined) {
|
|
46
|
+
throw new Error('[config] 非法写入:`ConfigAccess` 只能由 `createConfigAccess()` 产出');
|
|
26
47
|
}
|
|
27
|
-
|
|
48
|
+
write(value);
|
|
28
49
|
}
|
|
29
50
|
/** 按**已知键**从配置值里取字段(框架内置单元消费配置的单一入口;不做形状校验) */
|
|
30
51
|
export function readConfigKey(config, key) {
|
|
@@ -41,13 +62,24 @@ export function createResourcesContext(params) {
|
|
|
41
62
|
export function createConfigContext(params) {
|
|
42
63
|
return { env: params.env, log: params.log, disposer: params.disposer, resources: params.resources };
|
|
43
64
|
}
|
|
65
|
+
export function createClientsContext(params) {
|
|
66
|
+
return {
|
|
67
|
+
log: params.log,
|
|
68
|
+
disposer: params.disposer,
|
|
69
|
+
resources: params.resources,
|
|
70
|
+
get config() {
|
|
71
|
+
return params.configAccess.read();
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
44
75
|
export function createServiceContext(params) {
|
|
45
76
|
return {
|
|
46
77
|
log: params.log,
|
|
47
78
|
disposer: params.disposer,
|
|
48
79
|
resources: params.resources,
|
|
80
|
+
clients: params.clients,
|
|
49
81
|
get config() {
|
|
50
|
-
return
|
|
82
|
+
return params.configAccess.read();
|
|
51
83
|
},
|
|
52
84
|
};
|
|
53
85
|
}
|
|
@@ -57,23 +89,18 @@ export function createMiddlewareContext(params) {
|
|
|
57
89
|
log: params.log,
|
|
58
90
|
disposer: params.disposer,
|
|
59
91
|
services: params.services,
|
|
92
|
+
clients: params.clients,
|
|
60
93
|
get config() {
|
|
61
|
-
return
|
|
94
|
+
return params.configAccess.read();
|
|
62
95
|
},
|
|
63
96
|
};
|
|
64
97
|
}
|
|
65
98
|
export function createRouterContext(params) {
|
|
66
|
-
return { app: params.app, log: params.log, disposer: params.disposer, services: params.services };
|
|
67
|
-
}
|
|
68
|
-
export function createShutdownContext(params) {
|
|
69
99
|
return {
|
|
70
100
|
app: params.app,
|
|
71
101
|
log: params.log,
|
|
72
102
|
disposer: params.disposer,
|
|
73
|
-
resources: params.resources,
|
|
74
|
-
get config() {
|
|
75
|
-
return requireConfig(params.holder);
|
|
76
|
-
},
|
|
77
103
|
services: params.services,
|
|
104
|
+
clients: params.clients,
|
|
78
105
|
};
|
|
79
106
|
}
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
import type { Disposer } from '@taicode/common-base';
|
|
2
|
-
import type { LoggerLike } from '
|
|
2
|
+
import type { LoggerLike } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* 生命周期序(N1 §4 / N2 §2.5)。
|
|
5
5
|
*
|
|
6
6
|
* **每个阶段一个 `Disposer`**(`ctx.disposer`,所有槽位都有):在创建某个东西的地方当场
|
|
7
7
|
* `ctx.disposer.add(() => 释放它)` —— 创建与释放同处一地。
|
|
8
8
|
*
|
|
9
|
-
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → config → resources`
|
|
9
|
+
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → clients → config → resources`
|
|
10
10
|
* (后创建的先销毁;Prisma / Redis 这类资源最后才断)。
|
|
11
11
|
*
|
|
12
|
+
* **`clients` 为什么排在 `services` 之后关**:服务单元 `dispose()` 时可能还要落一次外部调用
|
|
13
|
+
* (落库、通知、上报),客户端必须先活着。
|
|
14
|
+
*
|
|
12
15
|
* **`services` 额外有逐单元生命周期**:
|
|
13
16
|
* - 单元之间**不得相互依赖**(`services` 的 ctx 没有 `services` 字段,编译期禁止);
|
|
14
17
|
* - `init` 按**对象声明序**,`dispose` **逆序**;
|
|
15
18
|
* - services 阶段内部**先 flush `ctx.disposer`**(构造期注册的清理),再逐单元 `dispose`。
|
|
16
19
|
*
|
|
17
|
-
* `middlewares`
|
|
20
|
+
* `middlewares` 按**对象键序**注册;它只有 `disposer`,没有逐单元生命周期。
|
|
18
21
|
*/
|
|
19
|
-
export declare const
|
|
22
|
+
export declare const RESOURCES_STAGE = "resources";
|
|
20
23
|
export declare const CONFIG_STAGE = "config";
|
|
24
|
+
export declare const CLIENTS_STAGE = "clients";
|
|
25
|
+
export declare const SERVICES_STAGE = "services";
|
|
21
26
|
export declare const MIDDLEWARES_STAGE = "middlewares";
|
|
22
27
|
export declare const ROUTERS_STAGE = "routers";
|
|
23
|
-
export declare const RESOURCES_STAGE = "resources";
|
|
24
28
|
/** `middlewares` 的**注册期日志**阶段标签(与生命周期阶段同名) */
|
|
25
29
|
export declare const MIDDLEWARES_LOG_STAGE = "middlewares";
|
|
26
30
|
/** 生命周期相位(逐单元日志字段 `phase`) */
|
|
@@ -47,13 +51,11 @@ export interface LifecycleUnitLogFields {
|
|
|
47
51
|
phase: LifecyclePhase;
|
|
48
52
|
}
|
|
49
53
|
/**
|
|
50
|
-
* `
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* `middlewares` 日志名字:`unit.name ?? '<service>:middleware[<index>]'`(仅用于注册期日志)。
|
|
54
|
+
* `middlewares` 日志名字:**对象键即单元名**(与 `services` 同口径)。
|
|
55
|
+
*
|
|
56
|
+
* 键为空串时退路 `<service>:middleware`(仅用于注册期日志,不影响注册序)。
|
|
55
57
|
*/
|
|
56
|
-
export declare function middlewareUnitName(service: string,
|
|
58
|
+
export declare function middlewareUnitName(service: string, key: string): string;
|
|
57
59
|
/** `initServiceUnits` 入参(参数签名内联对象类型已按 lint 规则外提) */
|
|
58
60
|
export interface InitServiceUnitsParams extends LifecycleLogContext {
|
|
59
61
|
/** `services(ctx)` 返回的对象(**对象键即单元名**) */
|
|
@@ -68,10 +70,6 @@ export interface DisposeServiceUnitsParams extends LifecycleLogContext {
|
|
|
68
70
|
/** `services(ctx)` 返回的对象(**对象键即单元名**) */
|
|
69
71
|
services?: Record<string, unknown>;
|
|
70
72
|
}
|
|
71
|
-
/**
|
|
72
|
-
* 关闭序:`services` 按声明序**逆序**逐项 `dispose?.()`。
|
|
73
|
-
*/
|
|
74
|
-
export declare function buildDisposeOrder(params: DisposeServiceUnitsParams): Array<() => void | Promise<void>>;
|
|
75
73
|
/**
|
|
76
74
|
* 关闭步 `disposeServices`:`services` 声明序逆序释放。
|
|
77
75
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../source/core/boot/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,eAAe,cAAc,CAAA;AAC1C,eAAO,MAAM,YAAY,WAAW,CAAA;AACpC,eAAO,MAAM,aAAa,YAAY,CAAA;AACtC,eAAO,MAAM,cAAc,aAAa,CAAA;AACxC,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAC9C,eAAO,MAAM,aAAa,YAAY,CAAA;AACtC,8CAA8C;AAC9C,eAAO,MAAM,qBAAqB,gBAAoB,CAAA;AAEtD,8BAA8B;AAC9B,eAAO,MAAM,oBAAoB,SAAS,CAAA;AAC1C,eAAO,MAAM,uBAAuB,YAAY,CAAA;AAChD,MAAM,MAAM,cAAc,GAAG,OAAO,oBAAoB,GAAG,OAAO,uBAAuB,CAAA;AAEzF;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,sCAAsC;IACtC,GAAG,CAAC,EAAE,UAAU,CAAA;CACjB;AAED,8DAA8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,cAAc,CAAA;CACtB;AAaD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,oDAAoD;AACpD,MAAM,WAAW,sBAAuB,SAAQ,mBAAmB;IACjE,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAmCD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpF;AAED,6EAA6E;AAC7E,MAAM,WAAW,yBAA0B,SAAQ,mBAAmB;IACpE,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAaD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtF;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,6CAA6C;IAC7C,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU5E"}
|
|
@@ -4,21 +4,25 @@
|
|
|
4
4
|
* **每个阶段一个 `Disposer`**(`ctx.disposer`,所有槽位都有):在创建某个东西的地方当场
|
|
5
5
|
* `ctx.disposer.add(() => 释放它)` —— 创建与释放同处一地。
|
|
6
6
|
*
|
|
7
|
-
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → config → resources`
|
|
7
|
+
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → clients → config → resources`
|
|
8
8
|
* (后创建的先销毁;Prisma / Redis 这类资源最后才断)。
|
|
9
9
|
*
|
|
10
|
+
* **`clients` 为什么排在 `services` 之后关**:服务单元 `dispose()` 时可能还要落一次外部调用
|
|
11
|
+
* (落库、通知、上报),客户端必须先活着。
|
|
12
|
+
*
|
|
10
13
|
* **`services` 额外有逐单元生命周期**:
|
|
11
14
|
* - 单元之间**不得相互依赖**(`services` 的 ctx 没有 `services` 字段,编译期禁止);
|
|
12
15
|
* - `init` 按**对象声明序**,`dispose` **逆序**;
|
|
13
16
|
* - services 阶段内部**先 flush `ctx.disposer`**(构造期注册的清理),再逐单元 `dispose`。
|
|
14
17
|
*
|
|
15
|
-
* `middlewares`
|
|
18
|
+
* `middlewares` 按**对象键序**注册;它只有 `disposer`,没有逐单元生命周期。
|
|
16
19
|
*/
|
|
17
|
-
export const
|
|
20
|
+
export const RESOURCES_STAGE = 'resources';
|
|
18
21
|
export const CONFIG_STAGE = 'config';
|
|
22
|
+
export const CLIENTS_STAGE = 'clients';
|
|
23
|
+
export const SERVICES_STAGE = 'services';
|
|
19
24
|
export const MIDDLEWARES_STAGE = 'middlewares';
|
|
20
25
|
export const ROUTERS_STAGE = 'routers';
|
|
21
|
-
export const RESOURCES_STAGE = 'resources';
|
|
22
26
|
/** `middlewares` 的**注册期日志**阶段标签(与生命周期阶段同名) */
|
|
23
27
|
export const MIDDLEWARES_LOG_STAGE = MIDDLEWARES_STAGE;
|
|
24
28
|
/** 生命周期相位(逐单元日志字段 `phase`) */
|
|
@@ -30,17 +34,16 @@ function isObject(value) {
|
|
|
30
34
|
/**
|
|
31
35
|
* `services` 有效名字:**对象键即单元名**(N1 §4:没有 `name` 字段)。
|
|
32
36
|
*/
|
|
33
|
-
|
|
37
|
+
function serviceUnitName(key) {
|
|
34
38
|
return key;
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
37
|
-
* `middlewares`
|
|
41
|
+
* `middlewares` 日志名字:**对象键即单元名**(与 `services` 同口径)。
|
|
42
|
+
*
|
|
43
|
+
* 键为空串时退路 `<service>:middleware`(仅用于注册期日志,不影响注册序)。
|
|
38
44
|
*/
|
|
39
|
-
export function middlewareUnitName(service,
|
|
40
|
-
|
|
41
|
-
return unit.name;
|
|
42
|
-
}
|
|
43
|
-
return `${service}:middleware[${index}]`;
|
|
45
|
+
export function middlewareUnitName(service, key) {
|
|
46
|
+
return key.length > 0 ? key : `${service}:middleware`;
|
|
44
47
|
}
|
|
45
48
|
async function callInit(unit) {
|
|
46
49
|
if (isObject(unit) && typeof unit.init === 'function') {
|
|
@@ -85,7 +88,7 @@ export async function initServiceUnits(params) {
|
|
|
85
88
|
/**
|
|
86
89
|
* 关闭序:`services` 按声明序**逆序**逐项 `dispose?.()`。
|
|
87
90
|
*/
|
|
88
|
-
|
|
91
|
+
function buildDisposeOrder(params) {
|
|
89
92
|
const steps = [];
|
|
90
93
|
for (const key of Object.keys(params.services ?? {}).reverse()) {
|
|
91
94
|
steps.push(() => runLifecycleUnit(params, serviceUnitName(key), params.services?.[key], LIFECYCLE_PHASE_DISPOSE));
|
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
* 固定关闭步(N1 §5)——**顺序写死在数组里**。
|
|
3
3
|
*
|
|
4
4
|
* `disposer` 是所有槽位 ctx 的标配:每个阶段一个 `Disposer`,在**创建处**注册释放。
|
|
5
|
-
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → config → resources`
|
|
5
|
+
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → clients → config → resources`
|
|
6
6
|
* (后创建的先销毁;Prisma / Redis 这类资源**最后**才断)。
|
|
7
7
|
*
|
|
8
8
|
* `services` 阶段内部保持既有语义:先 flush 自己的 `disposer`(原 `stopProducers`),
|
|
9
9
|
* 再 `disposeServices`(单元**逆序** `dispose`)。配置失效通道已删除,故没有 `unsubscribeConfig` 步。
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* `clients` 排在 `services` **之后**:服务单元 `dispose()` 时可能还要落一次外部调用。
|
|
12
|
+
*
|
|
13
|
+
* 固定七步:`flushRouters` → `flushMiddlewares` → `flushServices` → `disposeServices`
|
|
14
|
+
* → `flushClients` → `flushConfig` → `flushResources`。
|
|
13
15
|
*
|
|
14
16
|
* 每步失败记日志、不阻断后续,最后聚合上报。
|
|
15
17
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
declare const SHUTDOWN_ORDER: readonly ["flushRouters", "flushMiddlewares", "flushServices", "disposeServices", "flushClients", "flushConfig", "flushResources"];
|
|
19
|
+
type ShutdownStepName = (typeof SHUTDOWN_ORDER)[number];
|
|
20
|
+
type ShutdownHandles = Record<ShutdownStepName, () => void | Promise<void>>;
|
|
19
21
|
export interface ShutdownLogger {
|
|
20
22
|
error: (obj: unknown, msg?: string) => void;
|
|
21
23
|
}
|
|
@@ -24,4 +26,5 @@ export interface ShutdownLogger {
|
|
|
24
26
|
* (避免「一步报错导致后面资源没关」)。
|
|
25
27
|
*/
|
|
26
28
|
export declare function runShutdown(handles: ShutdownHandles, log: ShutdownLogger): Promise<void>;
|
|
29
|
+
export {};
|
|
27
30
|
//# sourceMappingURL=shutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../../source/core/boot/shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,cAAc,oIAQV,CAAA;AAEV,KAAK,gBAAgB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvD,KAAK,eAAe,GAAG,MAAM,CAAC,gBAAgB,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;AAE3E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAC5C;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAe9F"}
|
|
@@ -2,22 +2,25 @@
|
|
|
2
2
|
* 固定关闭步(N1 §5)——**顺序写死在数组里**。
|
|
3
3
|
*
|
|
4
4
|
* `disposer` 是所有槽位 ctx 的标配:每个阶段一个 `Disposer`,在**创建处**注册释放。
|
|
5
|
-
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → config → resources`
|
|
5
|
+
* 关闭时按阶段**逆序 flush**:`routers → middlewares → services → clients → config → resources`
|
|
6
6
|
* (后创建的先销毁;Prisma / Redis 这类资源**最后**才断)。
|
|
7
7
|
*
|
|
8
8
|
* `services` 阶段内部保持既有语义:先 flush 自己的 `disposer`(原 `stopProducers`),
|
|
9
9
|
* 再 `disposeServices`(单元**逆序** `dispose`)。配置失效通道已删除,故没有 `unsubscribeConfig` 步。
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* `clients` 排在 `services` **之后**:服务单元 `dispose()` 时可能还要落一次外部调用。
|
|
12
|
+
*
|
|
13
|
+
* 固定七步:`flushRouters` → `flushMiddlewares` → `flushServices` → `disposeServices`
|
|
14
|
+
* → `flushClients` → `flushConfig` → `flushResources`。
|
|
13
15
|
*
|
|
14
16
|
* 每步失败记日志、不阻断后续,最后聚合上报。
|
|
15
17
|
*/
|
|
16
|
-
|
|
18
|
+
const SHUTDOWN_ORDER = [
|
|
17
19
|
'flushRouters',
|
|
18
20
|
'flushMiddlewares',
|
|
19
21
|
'flushServices',
|
|
20
22
|
'disposeServices',
|
|
23
|
+
'flushClients',
|
|
21
24
|
'flushConfig',
|
|
22
25
|
'flushResources',
|
|
23
26
|
];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LoggerLike } from '../types.js';
|
|
2
|
+
import type { FastifyInstance } from 'fastify';
|
|
3
|
+
/**
|
|
4
|
+
* 内置信号处理(设计 §7.1 `activate` 尾部 / §7.2)。
|
|
5
|
+
*
|
|
6
|
+
* `SIGTERM` / `SIGINT` / `uncaughtException` / `unhandledRejection` ⇒ `app.close()`(触发 `onClose`
|
|
7
|
+
* 的关闭 6 步)⇒ `process.exit(0/1)`。**只有 `startServer` 装信号处理**(它一定 `listen`);
|
|
8
|
+
* `createTestServer` 不装——它跑在测试进程里,退出由测试框架决定。
|
|
9
|
+
*
|
|
10
|
+
* @returns detach 函数(移除本次注册的监听器);`startServer` 已把它挂到 `onClose` 上
|
|
11
|
+
*/
|
|
12
|
+
export declare function attachSignalHandlers(app: FastifyInstance, log: LoggerLike): () => void;
|
|
13
|
+
//# sourceMappingURL=signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../../source/core/boot/signal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,IAAI,CA2CtF"}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* 内置信号处理(设计 §7.1 `activate` 尾部 / §7.2)。
|
|
3
3
|
*
|
|
4
4
|
* `SIGTERM` / `SIGINT` / `uncaughtException` / `unhandledRejection` ⇒ `app.close()`(触发 `onClose`
|
|
5
|
-
* 的关闭 6 步)⇒ `process.exit(0/1)
|
|
5
|
+
* 的关闭 6 步)⇒ `process.exit(0/1)`。**只有 `startServer` 装信号处理**(它一定 `listen`);
|
|
6
|
+
* `createTestServer` 不装——它跑在测试进程里,退出由测试框架决定。
|
|
6
7
|
*
|
|
7
|
-
* @returns detach
|
|
8
|
+
* @returns detach 函数(移除本次注册的监听器);`startServer` 已把它挂到 `onClose` 上
|
|
8
9
|
*/
|
|
9
10
|
export function attachSignalHandlers(app, log) {
|
|
10
11
|
let closing = false;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Disposer } from '@taicode/common-base';
|
|
2
|
+
import type { ConfigAccess } from './context.js';
|
|
3
|
+
import type { ConfigEnv } from '../env.js';
|
|
4
|
+
import type { AppInstance, ClientsView, ErrorClassifier, LoggerLike, ResourcesView, Server } from '../types.js';
|
|
5
|
+
import type { FastifyInstance } from 'fastify';
|
|
6
|
+
/**
|
|
7
|
+
* 装配**步料**(不是装配流程)。
|
|
8
|
+
*
|
|
9
|
+
* `startServer` / `generateOpenApi` 各自在 `start.ts` / `openapi.ts` 里写明自己的步序——
|
|
10
|
+
* 这里只放「一步」的实现,**不含任何 `phase` / `mode` / 跳过集**。哪个入口跑哪几步,
|
|
11
|
+
* 在入口文件里一眼可见,不需要在数据结构和分支之间来回对照。
|
|
12
|
+
*/
|
|
13
|
+
/** 每个阶段一个 `Disposer`(创建与释放同处一地;关闭时按阶段逆序 flush) */
|
|
14
|
+
export interface StageDisposers {
|
|
15
|
+
resources: Disposer;
|
|
16
|
+
config: Disposer;
|
|
17
|
+
clients: Disposer;
|
|
18
|
+
services: Disposer;
|
|
19
|
+
middlewares: Disposer;
|
|
20
|
+
routers: Disposer;
|
|
21
|
+
}
|
|
22
|
+
/** 一次装配的**运行期上下文**(步料之间传递的、不放公共类型里的东西) */
|
|
23
|
+
export interface BootContext<R, C, CL, S> {
|
|
24
|
+
server: Server<R, C, CL, S>;
|
|
25
|
+
env: ConfigEnv;
|
|
26
|
+
/** 原生 Fastify 实例(对外返回的就是它) */
|
|
27
|
+
app: FastifyInstance;
|
|
28
|
+
/** 同一实例的框架视图(`request.ctx` 等类型增强的载体) */
|
|
29
|
+
instance: AppInstance;
|
|
30
|
+
log: LoggerLike;
|
|
31
|
+
/** 身份块的 `service`(日志标签用) */
|
|
32
|
+
service: string;
|
|
33
|
+
/** `config` 槽位的**读取能力**(出 spec 路径未产出 → `read()` 抛错) */
|
|
34
|
+
configAccess: ConfigAccess<C>;
|
|
35
|
+
disposers: StageDisposers;
|
|
36
|
+
}
|
|
37
|
+
/** 建 app + 六个阶段 `Disposer`(两个入口的**第一步**,内容完全相同) */
|
|
38
|
+
export declare function createBootContext<R, C, CL, S>(server: Server<R, C, CL, S>, env: ConfigEnv): BootContext<R, C, CL, S>;
|
|
39
|
+
/**
|
|
40
|
+
* 出文档用的上下文:**同一个 `BootContext` 形状,但实例是最小 Fastify**(无 logger /
|
|
41
|
+
* 无 requestId / 无 trustProxy,见 `createDocumentFastify`)。
|
|
42
|
+
*
|
|
43
|
+
* 形状不变是刻意的——`buildResources` / `registerRouters` 这些单步实现
|
|
44
|
+
* 因此**不需要知道自己在哪个入口跑**,轻量只体现在「实例怎么造」和「跑哪几步」上。
|
|
45
|
+
*/
|
|
46
|
+
export declare function createDocumentContext<R, C, CL, S>(server: Server<R, C, CL, S>, env: ConfigEnv): BootContext<R, C, CL, S>;
|
|
47
|
+
/**
|
|
48
|
+
* 取**已加载**配置的访问器(框架内置单元消费配置的唯一入口)。
|
|
49
|
+
*
|
|
50
|
+
* 出 spec 路径下 `config` 槽位未产出,读到即抛 `CONFIG_UNAVAILABLE`——
|
|
51
|
+
* 「构造期不得读配置」因此有运行期护栏,而不只是文档约定。
|
|
52
|
+
*/
|
|
53
|
+
export declare function createConfigReader<C>(configAccess: ConfigAccess<C>): (key: string) => unknown;
|
|
54
|
+
export interface ResourceBuildResult<R> {
|
|
55
|
+
/** 剔除了「编译期静态关闭」(值为 `false`)的键 */
|
|
56
|
+
resources: ResourcesView<R>;
|
|
57
|
+
/** 各资源注册的分类器合成结果(零个 = `undefined`) */
|
|
58
|
+
classifyResourceError: ErrorClassifier | undefined;
|
|
59
|
+
}
|
|
60
|
+
/** `resources(ctx)`:**只构造、不建连**(仅运行期入口执行) */
|
|
61
|
+
export declare function buildResources<R, C, CL, S>(ctx: BootContext<R, C, CL, S>): Promise<ResourceBuildResult<R>>;
|
|
62
|
+
/**
|
|
63
|
+
* core 装配:`identity` → `schema`(+ 路由契约守卫)→ `requestContext` → `cookie` →
|
|
64
|
+
* `response` → `openapi` → `requestId` 回吐。
|
|
65
|
+
*
|
|
66
|
+
* 仅运行期入口执行——它装的是「请求怎么被处理」,构建期没有请求。
|
|
67
|
+
*/
|
|
68
|
+
export declare function registerCoreStep<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, classifyResourceError?: ErrorClassifier): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* **文档 core** 装配:`identity` → `schema`(+ 路由契约守卫)→ `openapi`。
|
|
71
|
+
*
|
|
72
|
+
* 只装「把 zod schema 转成 OpenAPI 文档」所需的四件事。`requestContext` / `cookie` /
|
|
73
|
+
* `response` / `requestId` 不装:它们影响的是请求怎么被处理,而构建期一条请求都不会发。
|
|
74
|
+
* 守卫仍必须在——文档就是权限目录(§10-26)。
|
|
75
|
+
*/
|
|
76
|
+
export declare function registerDocumentCoreStep<R, C, CL, S>(ctx: BootContext<R, C, CL, S>): Promise<void>;
|
|
77
|
+
/** `config(ctx)`:**仅运行期**(出 spec 路径不跑) */
|
|
78
|
+
export declare function buildConfig<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, resources: ResourcesView<R>): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* `clients(ctx)`:**仅运行期**(需要 `config`,出 spec 路径不跑)。
|
|
81
|
+
*
|
|
82
|
+
* 外部客户端的地址 / 凭证来自业务配置,所以它必须排在 `config` 之后;
|
|
83
|
+
* 又因为多个 service 要共享同一份实例(而 `services` 之间禁止互依),所以它必须排在 `services` 之前。
|
|
84
|
+
*/
|
|
85
|
+
export declare function buildClients<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, resources: ResourcesView<R>): Promise<ClientsView<CL>>;
|
|
86
|
+
/** `services(ctx)`:**只构造**(`init()` 由调用方决定跑不跑) */
|
|
87
|
+
export declare function buildServices<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, resources: ResourcesView<R>, clients: ClientsView<CL>): Promise<Awaited<S>>;
|
|
88
|
+
/** `middlewares(ctx)`:按**对象键序**逐个 `register(app)`(两个入口都执行) */
|
|
89
|
+
export declare function registerMiddlewares<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, services: Awaited<S>, clients: ClientsView<CL>): Promise<void>;
|
|
90
|
+
/** 框架内置系统路由(`/` / `/health` / `/system/health` / `/system/openapi` / `/system/info`) */
|
|
91
|
+
export declare function registerSystemRoutesStep<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, services: Awaited<S>): void;
|
|
92
|
+
/** `routers(ctx)`:业务路由(文档与权限目录都从这里来) */
|
|
93
|
+
export declare function registerRouters<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, services: Awaited<S>, clients: ClientsView<CL>): Promise<void>;
|
|
94
|
+
/** 系统路由(出文档路径:不构造 `services`) */
|
|
95
|
+
export declare function registerDocumentSystemRoutesStep<R, C, CL, S>(ctx: BootContext<R, C, CL, S>): void;
|
|
96
|
+
/** 业务路由(出文档路径:不构造 `services` / `clients`;这是文档内容的**唯一**业务来源) */
|
|
97
|
+
export declare function registerDocumentRoutersStep<R, C, CL, S>(ctx: BootContext<R, C, CL, S>): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* 关闭流程(固定七步,顺序写在 `shutdown.ts` 里,不可覆盖)。
|
|
100
|
+
*
|
|
101
|
+
* 由 `onClose` 钩子触发;spec 入口在 `finally` 里 `close()` 同样会走它——
|
|
102
|
+
* 「构造了什么就释放什么」,构建脚本不再留下未释放的资源。
|
|
103
|
+
*/
|
|
104
|
+
export declare function buildShutdownFlow<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, services: Awaited<S>): () => Promise<void>;
|
|
105
|
+
/** 把关闭流程挂到 `onClose`(两个入口都挂:谁 `close()` 谁负责释放) */
|
|
106
|
+
export declare function installShutdownHook<R, C, CL, S>(ctx: BootContext<R, C, CL, S>, services: Awaited<S>): void;
|
|
107
|
+
//# sourceMappingURL=steps.d.ts.map
|