@taicode/common-server 4.0.0-beta.1 → 4.0.0-beta.10
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 +18 -15
- package/output/app/index.d.ts.map +1 -1
- package/output/app/index.js +330 -18
- package/output/auth/index.d.ts +73 -0
- package/output/auth/index.d.ts.map +1 -0
- package/output/auth/index.js +196 -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 +109 -0
- package/output/core/boot/context.d.ts.map +1 -0
- package/output/core/boot/context.js +145 -0
- package/output/core/boot/lifecycle.d.ts +206 -0
- package/output/core/boot/lifecycle.d.ts.map +1 -0
- package/output/core/boot/lifecycle.js +255 -0
- package/output/core/boot/shutdown.d.ts +34 -0
- package/output/core/boot/shutdown.d.ts.map +1 -0
- package/output/core/boot/shutdown.js +50 -0
- 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 +138 -0
- package/output/core/boot/steps.d.ts.map +1 -0
- package/output/core/boot/steps.js +259 -0
- package/output/core/entries.d.ts +151 -0
- package/output/core/entries.d.ts.map +1 -0
- package/output/core/entries.js +242 -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 +458 -0
- package/output/core/env.d.ts +83 -0
- package/output/core/env.d.ts.map +1 -0
- package/output/core/env.js +124 -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 +50 -0
- package/output/core/modules/response/index.d.ts.map +1 -0
- package/output/{app/core/response.js → core/modules/response/index.js} +31 -18
- 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 +205 -0
- package/output/core/resource.d.ts +56 -0
- package/output/core/resource.d.ts.map +1 -0
- package/output/core/resource.js +56 -0
- package/output/core/test-support/database.d.ts +89 -0
- package/output/core/test-support/database.d.ts.map +1 -0
- package/output/core/test-support/database.js +131 -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 +111 -0
- package/output/core/test-support/environment.d.ts +38 -0
- package/output/core/test-support/environment.d.ts.map +1 -0
- package/output/core/test-support/environment.js +45 -0
- package/output/core/test-support/service-context.d.ts +64 -0
- package/output/core/test-support/service-context.d.ts.map +1 -0
- package/output/core/test-support/service-context.js +63 -0
- package/output/core/test-support/service-context.test.d.ts +2 -0
- package/output/core/test-support/service-context.test.d.ts.map +1 -0
- package/output/core/test-support/service-context.test.js +55 -0
- package/output/core/test-support/test-server.d.ts +154 -0
- package/output/core/test-support/test-server.d.ts.map +1 -0
- package/output/core/test-support/test-server.js +114 -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 +296 -0
- package/output/core/test-support/testdata.d.ts +255 -0
- package/output/core/test-support/testdata.d.ts.map +1 -0
- package/output/core/test-support/testdata.js +271 -0
- package/output/core/test-support/testdata.test.d.ts +2 -0
- package/output/core/test-support/testdata.test.d.ts.map +1 -0
- package/output/core/test-support/testdata.test.js +334 -0
- package/output/{app → core}/type-augment.d.ts +2 -2
- package/output/core/type-augment.d.ts.map +1 -0
- package/output/core/types.d.ts +582 -0
- 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 +28 -0
- package/output/index.d.ts +10 -4
- package/output/index.d.ts.map +1 -1
- package/output/index.js +25 -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 +43 -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-limiter → rate-limit}/memory-store.d.ts +6 -0
- package/output/rate-limit/memory-store.d.ts.map +1 -0
- package/output/{rate-limiter → rate-limit}/memory-store.js +8 -0
- package/output/{rate-limiter → rate-limit}/redis-store.d.ts +18 -0
- package/output/rate-limit/redis-store.d.ts.map +1 -0
- package/output/{rate-limiter → rate-limit}/redis-store.js +35 -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-limit/types.d.ts +45 -0
- 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} +12 -7
- package/output/redis/index.d.ts.map +1 -0
- package/output/{app/redis.js → redis/index.js} +15 -5
- 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 +5 -5
- 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 -48
- package/output/app/boot.d.ts.map +0 -1
- package/output/app/boot.js +0 -123
- 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 -68
- package/output/app/context.d.ts.map +0 -1
- package/output/app/context.js +0 -73
- 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 -32
- package/output/app/define-server.negative-cases.d.ts.map +0 -1
- package/output/app/define-server.negative-cases.js +0 -209
- 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 -29
- package/output/app/entries.d.ts.map +0 -1
- package/output/app/entries.js +0 -64
- 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 -125
- 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 -155
- package/output/app/lifecycle.d.ts +0 -70
- package/output/app/lifecycle.d.ts.map +0 -1
- package/output/app/lifecycle.js +0 -99
- 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 -152
- 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 -148
- 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 -197
- package/output/app/shutdown.d.ts +0 -22
- package/output/app/shutdown.d.ts.map +0 -1
- package/output/app/shutdown.js +0 -30
- 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 -103
- 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 +0 -211
- 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 +0 -27
- 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}/redis-store.test.d.ts +0 -0
- /package/output/{redis-cache/redis-cache.js → redis/cache.js} +0 -0
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { ErrorClassifier } from './response.js';
|
|
2
|
-
import type { ConfigEnv } from '../env.js';
|
|
3
|
-
import type { AppIdentity } from '../types.js';
|
|
4
|
-
import type { FastifyInstance } from 'fastify';
|
|
5
|
-
export { registerCookie, resolveCookieNames, resolveCookieDomain } from './cookie.js';
|
|
6
|
-
export { registerResponse, createSuccessResponse, createErrorResponse } from './response.js';
|
|
7
|
-
export { registerOpenApi, DOC_ROUTE_PREFIX, DOC_SPEC_ROUTE } from './openapi.js';
|
|
8
|
-
export { registerRequestId, REQUEST_ID_HEADER, REQUEST_ID_LOG_LABEL } from './request-id.js';
|
|
9
|
-
export { createLoggerOptions, LOG_REDACT_PATHS } from './logging.js';
|
|
10
|
-
export { SERVER_IDENTITY, attachServerIdentity, readServerIdentity } from './identity.js';
|
|
11
|
-
export type { AuthCookieOptions, CookieCoreOptions } from './cookie.js';
|
|
12
|
-
export type { ResponseCoreOptions, ResponseEnvelope } from './response.js';
|
|
13
|
-
export type { OpenApiCoreOptions } from './openapi.js';
|
|
14
|
-
/**
|
|
15
|
-
* core `schema`(设计 §5.1)——**框架内置、锁定、不可替换/修改**。
|
|
16
|
-
*
|
|
17
|
-
* 装配 `fastify-type-provider-zod` 的 validator / serializer compiler;响应 schema 由框架统一
|
|
18
|
-
* 生成(业务侧用 `../schema/index.js` 的 `responseSchema`)。
|
|
19
|
-
*/
|
|
20
|
-
export declare function registerSchema(app: FastifyInstance): void;
|
|
21
|
-
/**
|
|
22
|
-
* core 步骤 `createFastify`(`prepare`)。
|
|
23
|
-
*
|
|
24
|
-
* **总是**建 pino logger(level = `LOG_LEVEL`,默认 `info`) + 内置 `requestId`(入站 `x-request-id`
|
|
25
|
-
* 复用 / `randomUUID`,日志字段 `requestId`)。`trustProxy: true` 与四家现状一致。
|
|
26
|
-
*/
|
|
27
|
-
export declare function createFastify(env: ConfigEnv): FastifyInstance;
|
|
28
|
-
/** core 装配入参 */
|
|
29
|
-
export interface CoreRegistrationOptions {
|
|
30
|
-
/** 身份块(`service` / `title` / `version`):openapi + 内置单元从这里读 */
|
|
31
|
-
identity: AppIdentity;
|
|
32
|
-
env: ConfigEnv;
|
|
33
|
-
/** 数据层错误分类(资源包提供;缺省 = 落 `UNKNOWN_ERROR`) */
|
|
34
|
-
classifyError?: ErrorClassifier;
|
|
35
|
-
/** 取**已加载**配置中某个键的访问器(cookie domain 等**惰性**取值;不得在构造期调用) */
|
|
36
|
-
readConfig: (key: string) => unknown;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* core 装配:`schema` → `cookie` → `response` → `openapi` → 路由注册表。
|
|
40
|
-
* `requestId` 的响应回吐 hook 一并注册。**构造期不读配置**(`cookie` 的 domain 在请求期惰性读取),
|
|
41
|
-
* 故出 spec 路径(`readConfig` 不可用)不会触发。
|
|
42
|
-
*/
|
|
43
|
-
export declare function registerCore(app: FastifyInstance, options: CoreRegistrationOptions): Promise<void>;
|
|
44
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/app/core/index.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACrF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEzF,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACvE,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC1E,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEtD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAMzD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,GAAG,eAAe,CAM7D;AAED,gBAAgB;AAChB,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,QAAQ,EAAE,WAAW,CAAA;IACrB,GAAG,EAAE,SAAS,CAAA;IACd,4CAA4C;IAC5C,aAAa,CAAC,EAAE,eAAe,CAAA;IAC/B,2DAA2D;IAC3D,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAA;CACrC;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAaxG"}
|
package/output/app/core/index.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import Fastify from 'fastify';
|
|
2
|
-
import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod';
|
|
3
|
-
import { installRegisteredOperations } from '../permission-operations.js';
|
|
4
|
-
import { registerCookie } from './cookie.js';
|
|
5
|
-
import { attachServerIdentity } from './identity.js';
|
|
6
|
-
import { createLoggerOptions } from './logging.js';
|
|
7
|
-
import { registerOpenApi } from './openapi.js';
|
|
8
|
-
import { createRequestIdOptions, registerRequestId } from './request-id.js';
|
|
9
|
-
import { registerResponse } from './response.js';
|
|
10
|
-
export { registerCookie, resolveCookieNames, resolveCookieDomain } from './cookie.js';
|
|
11
|
-
export { registerResponse, createSuccessResponse, createErrorResponse } from './response.js';
|
|
12
|
-
export { registerOpenApi, DOC_ROUTE_PREFIX, DOC_SPEC_ROUTE } from './openapi.js';
|
|
13
|
-
export { registerRequestId, REQUEST_ID_HEADER, REQUEST_ID_LOG_LABEL } from './request-id.js';
|
|
14
|
-
export { createLoggerOptions, LOG_REDACT_PATHS } from './logging.js';
|
|
15
|
-
export { SERVER_IDENTITY, attachServerIdentity, readServerIdentity } from './identity.js';
|
|
16
|
-
/**
|
|
17
|
-
* core `schema`(设计 §5.1)——**框架内置、锁定、不可替换/修改**。
|
|
18
|
-
*
|
|
19
|
-
* 装配 `fastify-type-provider-zod` 的 validator / serializer compiler;响应 schema 由框架统一
|
|
20
|
-
* 生成(业务侧用 `../schema/index.js` 的 `responseSchema`)。
|
|
21
|
-
*/
|
|
22
|
-
export function registerSchema(app) {
|
|
23
|
-
app.setValidatorCompiler(validatorCompiler);
|
|
24
|
-
app.setSerializerCompiler(serializerCompiler);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* core 步骤 `createFastify`(`prepare`)。
|
|
28
|
-
*
|
|
29
|
-
* **总是**建 pino logger(level = `LOG_LEVEL`,默认 `info`) + 内置 `requestId`(入站 `x-request-id`
|
|
30
|
-
* 复用 / `randomUUID`,日志字段 `requestId`)。`trustProxy: true` 与四家现状一致。
|
|
31
|
-
*/
|
|
32
|
-
export function createFastify(env) {
|
|
33
|
-
return Fastify({
|
|
34
|
-
trustProxy: true,
|
|
35
|
-
logger: createLoggerOptions(env),
|
|
36
|
-
...createRequestIdOptions(),
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* core 装配:`schema` → `cookie` → `response` → `openapi` → 路由注册表。
|
|
41
|
-
* `requestId` 的响应回吐 hook 一并注册。**构造期不读配置**(`cookie` 的 domain 在请求期惰性读取),
|
|
42
|
-
* 故出 spec 路径(`readConfig` 不可用)不会触发。
|
|
43
|
-
*/
|
|
44
|
-
export async function registerCore(app, options) {
|
|
45
|
-
attachServerIdentity(app, options.identity);
|
|
46
|
-
registerSchema(app); // schema → zod compiler
|
|
47
|
-
registerCookie(app, { env: options.env, readConfig: options.readConfig });
|
|
48
|
-
registerResponse(app, { classifyError: options.classifyError });
|
|
49
|
-
// await:确定性冲刷插件队列,保证 swagger 的 root `onRoute` 钩子在路由注册之前就位
|
|
50
|
-
await registerOpenApi(app, {
|
|
51
|
-
title: options.identity.title,
|
|
52
|
-
version: options.identity.version,
|
|
53
|
-
});
|
|
54
|
-
// 路由注册表:在 routers 阶段之前挂 root `onRoute`,供 `auth` 权限自注册读取(与 swagger 解耦)
|
|
55
|
-
installRegisteredOperations(app);
|
|
56
|
-
registerRequestId(app); // 响应回吐 x-request-id
|
|
57
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { ConfigEnv } from '../env.js';
|
|
2
|
-
import type { FastifyServerOptions } from 'fastify';
|
|
3
|
-
/**
|
|
4
|
-
* core `logging`(设计 §5.1)——**框架内置、锁定、不可替换/修改**。
|
|
5
|
-
*
|
|
6
|
-
* `createFastify` **总是**建 pino logger(级别取 `LOG_LEVEL`,默认 `info`);原 `logging: false`
|
|
7
|
-
* 开关随 `CoreOptions` 一并删除,日志始终开启,不再由 `debug` 控制。
|
|
8
|
-
*/
|
|
9
|
-
/** 默认 `redact` 路径(设计 §5.1) */
|
|
10
|
-
export declare const LOG_REDACT_PATHS: readonly ["authorization", "cookie", "set-cookie", "req.headers.authorization", "req.headers.cookie", "*.token", "*.password", "*.secretKey", "*.secretValue"];
|
|
11
|
-
/** 构造 Fastify 的 logger 选项 */
|
|
12
|
-
export declare function createLoggerOptions(env: ConfigEnv): FastifyServerOptions['logger'];
|
|
13
|
-
//# sourceMappingURL=logging.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../source/app/core/logging.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD;;;;;GAKG;AAEH,8BAA8B;AAC9B,eAAO,MAAM,gBAAgB,gKAUnB,CAAA;AAEV,6BAA6B;AAC7B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAQlF"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { FastifyInstance } from 'fastify';
|
|
2
|
-
/**
|
|
3
|
-
* core `openapi`(设计 §5.1)——**框架内置、锁定、不可替换/修改**。
|
|
4
|
-
*
|
|
5
|
-
* `@fastify/swagger` + `@scalar/fastify-api-reference`;`/reference` 与 `/reference/openapi.json`;
|
|
6
|
-
* `servers: [{ url: '/' }]`(构建期不依赖 env / DB);`version` 取 `app.version`(必填,无默认);
|
|
7
|
-
* `securitySchemes.bearerAuth`;`onListen` 打印实际地址。
|
|
8
|
-
*/
|
|
9
|
-
export declare const DOC_ROUTE_PREFIX = "/reference";
|
|
10
|
-
export declare const DOC_SPEC_ROUTE = "/reference/openapi.json";
|
|
11
|
-
export declare const OPENAPI_SPEC_VERSION = "3.0.3";
|
|
12
|
-
export interface OpenApiCoreOptions {
|
|
13
|
-
title: string;
|
|
14
|
-
version: string;
|
|
15
|
-
}
|
|
16
|
-
export declare function registerOpenApi(app: FastifyInstance, options: OpenApiCoreOptions): Promise<void>;
|
|
17
|
-
//# sourceMappingURL=openapi.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../source/app/core/openapi.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C;;;;;;GAMG;AAEH,eAAO,MAAM,gBAAgB,eAAe,CAAA;AAC5C,eAAO,MAAM,cAAc,4BAA4B,CAAA;AACvD,eAAO,MAAM,oBAAoB,UAAU,CAAA;AAE3C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BtG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../../../source/app/core/request-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,iBAAiB,iBAAiB,CAAA;AAC/C,eAAO,MAAM,oBAAoB,cAAc,CAAA;AAE/C,qEAAqE;AACrE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOpG;AAED,sCAAsC;AACtC,wBAAgB,sBAAsB,IAAI;IACxC,eAAe,EAAE,MAAM,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;KAAE,KAAK,MAAM,CAAA;CAC1F,CAOA;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAwB5D"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { SystemError } from '../errors.js';
|
|
2
|
-
import type { FastifyInstance } from 'fastify';
|
|
3
|
-
/**
|
|
4
|
-
* core `response`(设计 §5.1 / §8,错误契约 D7)——**框架内置、锁定、不可替换/修改**。
|
|
5
|
-
*
|
|
6
|
-
* - 成功信封 `{ status: 'SUCCESS', message: 'ok', data }`(由 `preSerialization` 统一包裹)。
|
|
7
|
-
* - 错误信封 `{ status: <错误码字符串>, message, data: null }`。
|
|
8
|
-
* - `setErrorHandler` 固定分支:`UserError`→400(`error.status` 字面量)/ `SystemError`→500 /
|
|
9
|
-
* zod→400 / serde→500 / 数据层(资源包的 `classifyError`)→500 / 未知→500;**禁止按 `error.type` 细分**。
|
|
10
|
-
* - `setNotFoundHandler` → 404 + `NOT_IMPLEMENTED`(落 `warn`,文案对齐 expense/notice)。
|
|
11
|
-
* - 错误日志分级:`UserError` / zod → `warn`,其余 → `error`(带 stack)。
|
|
12
|
-
* - **错误只给稳定码**(`status` 放错误码字符串),文案不归框架(由前端 / i18n 决定,§10-6)。
|
|
13
|
-
*/
|
|
14
|
-
export declare const SUCCESS_STATUS = "SUCCESS";
|
|
15
|
-
export declare const NOT_IMPLEMENTED_STATUS = "NOT_IMPLEMENTED";
|
|
16
|
-
export declare const INVALID_INPUT_STATUS = "INVALID_INPUT";
|
|
17
|
-
export declare const SERIALIZATION_ERROR_STATUS = "RESPONSE_SERIALIZATION_ERROR";
|
|
18
|
-
export declare const UNKNOWN_ERROR_STATUS = "UNKNOWN_ERROR";
|
|
19
|
-
/** 通用兜底文案(仅在 `error.message` 为空时使用) */
|
|
20
|
-
export declare const DEFAULT_USER_MESSAGE = "\u8BF7\u6C42\u5931\u8D25";
|
|
21
|
-
export declare const DEFAULT_SYSTEM_MESSAGE = "\u7CFB\u7EDF\u9519\u8BEF";
|
|
22
|
-
export interface ResponseEnvelope<T> {
|
|
23
|
-
status: string;
|
|
24
|
-
message: string;
|
|
25
|
-
data: T;
|
|
26
|
-
}
|
|
27
|
-
export declare function createSuccessResponse<T>(data: T): ResponseEnvelope<T>;
|
|
28
|
-
export declare function createErrorResponse(status: string, message: string): ResponseEnvelope<null>;
|
|
29
|
-
/**
|
|
30
|
-
* 数据层错误分类器(资源包里带 `classifyError` 的值的裸函数形态)。
|
|
31
|
-
*
|
|
32
|
-
* 资源包(`resources` 槽位返回值)里任何提供 `classifyError` 的值都会被用作响应错误分类;
|
|
33
|
-
* 都没有时错误落 `UNKNOWN_ERROR` 兜底。
|
|
34
|
-
*/
|
|
35
|
-
export type ErrorClassifier = (error: unknown) => SystemError | null;
|
|
36
|
-
export interface ResponseCoreOptions {
|
|
37
|
-
/** Prisma / 数据层错误分类(缺省 = 不做数据层分类) */
|
|
38
|
-
classifyError?: ErrorClassifier;
|
|
39
|
-
}
|
|
40
|
-
export declare function registerResponse(app: FastifyInstance, options?: ResponseCoreOptions): void;
|
|
41
|
-
//# sourceMappingURL=response.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../source/app/core/response.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAa,MAAM,cAAc,CAAA;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,cAAc,YAAY,CAAA;AACvC,eAAO,MAAM,sBAAsB,oBAAoB,CAAA;AACvD,eAAO,MAAM,oBAAoB,kBAAkB,CAAA;AACnD,eAAO,MAAM,0BAA0B,iCAAiC,CAAA;AACxE,eAAO,MAAM,oBAAoB,kBAAkB,CAAA;AAEnD,uCAAuC;AACvC,eAAO,MAAM,oBAAoB,6BAAS,CAAA;AAC1C,eAAO,MAAM,sBAAsB,6BAAS,CAAA;AAE5C,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAA;CACR;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAErE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAE3F;AAsBD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,WAAW,GAAG,IAAI,CAAA;AAEpE,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,aAAa,CAAC,EAAE,eAAe,CAAA;CAChC;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI,CAyD9F"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { ServerConfig } from './types.js';
|
|
2
|
-
/** #1 `resources` 看不到 `config` */
|
|
3
|
-
export declare function resourcesCannotSeeConfig(): void;
|
|
4
|
-
/** #2 `resources` 看不到 `services` */
|
|
5
|
-
export declare function resourcesCannotSeeServices(): void;
|
|
6
|
-
/** #3 `config` 看不到 `services` */
|
|
7
|
-
export declare function configCannotSeeServices(): void;
|
|
8
|
-
/** #4 `services` 看不到 `services`(禁 service 互依) */
|
|
9
|
-
export declare function servicesCannotSeeServices(): void;
|
|
10
|
-
/** #5 `routers` 看不到 `resources`(禁绕层直连数据层) */
|
|
11
|
-
export declare function routersCannotSeeResources(): void;
|
|
12
|
-
/** #6 `routers` 看不到 `config` */
|
|
13
|
-
export declare function routersCannotSeeConfig(): void;
|
|
14
|
-
/** #7 service 值声明 `dependsOn` → 该值塌成 `never` */
|
|
15
|
-
export declare function serviceValueCannotDeclareDependsOn(): void;
|
|
16
|
-
/** #8 service 值是原始类型 → 被拒(防把配置塞进 services) */
|
|
17
|
-
export declare function serviceValueCannotBePrimitive(): void;
|
|
18
|
-
/** #9 `startServer` 只接受品牌产物,裸 `ServerConfig` 编译失败 */
|
|
19
|
-
export declare function startServerRejectsBareConfig(bare: ServerConfig<unknown, unknown, unknown>): void;
|
|
20
|
-
/** #10 `app.version` 必填 */
|
|
21
|
-
export declare function appVersionIsRequired(): void;
|
|
22
|
-
/** #11 `cache: false` 静态关闭:键被 `Live<>` 从资源视图剔除 */
|
|
23
|
-
export declare function staticallyDisabledResourceIsRemoved(): void;
|
|
24
|
-
/** #12 `config` 看不到 `app` */
|
|
25
|
-
export declare function configCannotSeeApp(): void;
|
|
26
|
-
/** #13 `middlewares` 看不到 `resources`(中间件禁直连数据层) */
|
|
27
|
-
export declare function middlewaresCannotSeeResources(): void;
|
|
28
|
-
/** #14 `middlewares` 看不到 `env` */
|
|
29
|
-
export declare function middlewaresCannotSeeEnv(): void;
|
|
30
|
-
/** #15 `services` 看不到 `env`(服务层禁读 env) */
|
|
31
|
-
export declare function servicesCannotSeeEnv(): void;
|
|
32
|
-
//# sourceMappingURL=define-server.negative-cases.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"define-server.negative-cases.d.ts","sourceRoot":"","sources":["../../source/app/define-server.negative-cases.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAgB9C,kCAAkC;AAClC,wBAAgB,wBAAwB,IAAI,IAAI,CAU/C;AAED,oCAAoC;AACpC,wBAAgB,0BAA0B,IAAI,IAAI,CAUjD;AAED,iCAAiC;AACjC,wBAAgB,uBAAuB,IAAI,IAAI,CAa9C;AAED,iDAAiD;AACjD,wBAAgB,yBAAyB,IAAI,IAAI,CAahD;AAED,6CAA6C;AAC7C,wBAAgB,yBAAyB,IAAI,IAAI,CAYhD;AAED,gCAAgC;AAChC,wBAAgB,sBAAsB,IAAI,IAAI,CAY7C;AAED,gDAAgD;AAChD,wBAAgB,kCAAkC,IAAI,IAAI,CAUzD;AAED,8CAA8C;AAC9C,wBAAgB,6BAA6B,IAAI,IAAI,CAUpD;AAED,qDAAqD;AACrD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,CAGhG;AAED,2BAA2B;AAC3B,wBAAgB,oBAAoB,IAAI,IAAI,CAU3C;AAED,kDAAkD;AAClD,wBAAgB,mCAAmC,IAAI,IAAI,CAa1D;AAED,6BAA6B;AAC7B,wBAAgB,kBAAkB,IAAI,IAAI,CAazC;AAED,mDAAmD;AACnD,wBAAgB,6BAA6B,IAAI,IAAI,CAapD;AAED,kCAAkC;AAClC,wBAAgB,uBAAuB,IAAI,IAAI,CAa9C;AAED,0CAA0C;AAC1C,wBAAgB,oBAAoB,IAAI,IAAI,CAa3C"}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { defineServer, startServer } from './entries.js';
|
|
2
|
-
/**
|
|
3
|
-
* N2 §4 的 **15 条负向用例**:这些写法**必须编译失败**,全部由 `tsc --noEmit` 覆盖
|
|
4
|
-
* (**不进**运行期 vitest 断言)。
|
|
5
|
-
*
|
|
6
|
-
* 文件名刻意**不带** `.test.ts`:它由 `tsc --noEmit` 校验,不被 vitest 当作测试文件执行。
|
|
7
|
-
* 每个用例的 `@ts-expect-error` 必须**确有错误**,否则 tsc 会报「未使用」而失败。
|
|
8
|
-
*
|
|
9
|
-
* 说明:`defineServer` 的调用结果一律不用 —— 这些函数只作编译期证据。
|
|
10
|
-
*/
|
|
11
|
-
const identity = { service: 'negative-cases', title: 'Negative Cases', version: '1.0.0' };
|
|
12
|
-
/** #1 `resources` 看不到 `config` */
|
|
13
|
-
export function resourcesCannotSeeConfig() {
|
|
14
|
-
defineServer({
|
|
15
|
-
app: identity,
|
|
16
|
-
// @ts-expect-error `config` 不存在于 ResourcesContext
|
|
17
|
-
resources: ({ config }) => ({ config }),
|
|
18
|
-
config: () => ({}),
|
|
19
|
-
services: () => ({}),
|
|
20
|
-
middlewares: () => [],
|
|
21
|
-
routers: () => undefined,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
/** #2 `resources` 看不到 `services` */
|
|
25
|
-
export function resourcesCannotSeeServices() {
|
|
26
|
-
defineServer({
|
|
27
|
-
app: identity,
|
|
28
|
-
// @ts-expect-error `services` 不存在于 ResourcesContext
|
|
29
|
-
resources: ({ services }) => ({ services }),
|
|
30
|
-
config: () => ({}),
|
|
31
|
-
services: () => ({}),
|
|
32
|
-
middlewares: () => [],
|
|
33
|
-
routers: () => undefined,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
/** #3 `config` 看不到 `services` */
|
|
37
|
-
export function configCannotSeeServices() {
|
|
38
|
-
defineServer({
|
|
39
|
-
app: identity,
|
|
40
|
-
resources: () => ({}),
|
|
41
|
-
config: (ctx) => {
|
|
42
|
-
// @ts-expect-error `services` 不存在于 ConfigContext
|
|
43
|
-
void ctx.services;
|
|
44
|
-
return {};
|
|
45
|
-
},
|
|
46
|
-
services: () => ({}),
|
|
47
|
-
middlewares: () => [],
|
|
48
|
-
routers: () => undefined,
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/** #4 `services` 看不到 `services`(禁 service 互依) */
|
|
52
|
-
export function servicesCannotSeeServices() {
|
|
53
|
-
defineServer({
|
|
54
|
-
app: identity,
|
|
55
|
-
resources: () => ({}),
|
|
56
|
-
config: () => ({}),
|
|
57
|
-
services: (ctx) => {
|
|
58
|
-
// @ts-expect-error `services` 不存在于 ServiceContext(禁互依)
|
|
59
|
-
void ctx.services;
|
|
60
|
-
return {};
|
|
61
|
-
},
|
|
62
|
-
middlewares: () => [],
|
|
63
|
-
routers: () => undefined,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/** #5 `routers` 看不到 `resources`(禁绕层直连数据层) */
|
|
67
|
-
export function routersCannotSeeResources() {
|
|
68
|
-
defineServer({
|
|
69
|
-
app: identity,
|
|
70
|
-
resources: () => ({ database: {} }),
|
|
71
|
-
config: () => ({}),
|
|
72
|
-
services: () => ({}),
|
|
73
|
-
middlewares: () => [],
|
|
74
|
-
routers: (ctx) => {
|
|
75
|
-
// @ts-expect-error `resources` 不存在于 RouterContext
|
|
76
|
-
void ctx.resources.database;
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
/** #6 `routers` 看不到 `config` */
|
|
81
|
-
export function routersCannotSeeConfig() {
|
|
82
|
-
defineServer({
|
|
83
|
-
app: identity,
|
|
84
|
-
resources: () => ({}),
|
|
85
|
-
config: () => ({}),
|
|
86
|
-
services: () => ({}),
|
|
87
|
-
middlewares: () => [],
|
|
88
|
-
routers: (ctx) => {
|
|
89
|
-
// @ts-expect-error `config` 不存在于 RouterContext
|
|
90
|
-
void ctx.config;
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
/** #7 service 值声明 `dependsOn` → 该值塌成 `never` */
|
|
95
|
-
export function serviceValueCannotDeclareDependsOn() {
|
|
96
|
-
defineServer({
|
|
97
|
-
app: identity,
|
|
98
|
-
resources: () => ({}),
|
|
99
|
-
config: () => ({}),
|
|
100
|
-
// @ts-expect-error `dependsOn` 声明使该值塌成 never
|
|
101
|
-
services: () => ({ a: { dependsOn: ['b'] } }),
|
|
102
|
-
middlewares: () => [],
|
|
103
|
-
routers: () => undefined,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
/** #8 service 值是原始类型 → 被拒(防把配置塞进 services) */
|
|
107
|
-
export function serviceValueCannotBePrimitive() {
|
|
108
|
-
defineServer({
|
|
109
|
-
app: identity,
|
|
110
|
-
resources: () => ({}),
|
|
111
|
-
config: () => ({}),
|
|
112
|
-
// @ts-expect-error 原始类型值被 ServicesShape 拒绝
|
|
113
|
-
services: () => ({ count: 1 }),
|
|
114
|
-
middlewares: () => [],
|
|
115
|
-
routers: () => undefined,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
/** #9 `startServer` 只接受品牌产物,裸 `ServerConfig` 编译失败 */
|
|
119
|
-
export function startServerRejectsBareConfig(bare) {
|
|
120
|
-
// @ts-expect-error 缺 `__brand`,不是 Server
|
|
121
|
-
void startServer(bare);
|
|
122
|
-
}
|
|
123
|
-
/** #10 `app.version` 必填 */
|
|
124
|
-
export function appVersionIsRequired() {
|
|
125
|
-
defineServer({
|
|
126
|
-
// @ts-expect-error `AppIdentity.version` 必填
|
|
127
|
-
app: { service: 'no-version', title: 'No Version' },
|
|
128
|
-
resources: () => ({}),
|
|
129
|
-
config: () => ({}),
|
|
130
|
-
services: () => ({}),
|
|
131
|
-
middlewares: () => [],
|
|
132
|
-
routers: () => undefined,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
/** #11 `cache: false` 静态关闭:键被 `Live<>` 从资源视图剔除 */
|
|
136
|
-
export function staticallyDisabledResourceIsRemoved() {
|
|
137
|
-
defineServer({
|
|
138
|
-
app: identity,
|
|
139
|
-
resources: () => ({ cache: false, database: { query: () => '' } }),
|
|
140
|
-
config: (ctx) => {
|
|
141
|
-
// @ts-expect-error `cache: false` 的键已被 `Live<>` 剔除
|
|
142
|
-
void ctx.cache;
|
|
143
|
-
return {};
|
|
144
|
-
},
|
|
145
|
-
services: () => ({}),
|
|
146
|
-
middlewares: () => [],
|
|
147
|
-
routers: () => undefined,
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
/** #12 `config` 看不到 `app` */
|
|
151
|
-
export function configCannotSeeApp() {
|
|
152
|
-
defineServer({
|
|
153
|
-
app: identity,
|
|
154
|
-
resources: () => ({}),
|
|
155
|
-
config: (ctx) => {
|
|
156
|
-
// @ts-expect-error `app` 不存在于 ConfigContext
|
|
157
|
-
void ctx.app;
|
|
158
|
-
return {};
|
|
159
|
-
},
|
|
160
|
-
services: () => ({}),
|
|
161
|
-
middlewares: () => [],
|
|
162
|
-
routers: () => undefined,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
/** #13 `middlewares` 看不到 `resources`(中间件禁直连数据层) */
|
|
166
|
-
export function middlewaresCannotSeeResources() {
|
|
167
|
-
defineServer({
|
|
168
|
-
app: identity,
|
|
169
|
-
resources: () => ({ database: {} }),
|
|
170
|
-
config: () => ({}),
|
|
171
|
-
services: () => ({}),
|
|
172
|
-
middlewares: (ctx) => {
|
|
173
|
-
// @ts-expect-error `resources` 不存在于 MiddlewareContext
|
|
174
|
-
void ctx.resources.database;
|
|
175
|
-
return [];
|
|
176
|
-
},
|
|
177
|
-
routers: () => undefined,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
/** #14 `middlewares` 看不到 `env` */
|
|
181
|
-
export function middlewaresCannotSeeEnv() {
|
|
182
|
-
defineServer({
|
|
183
|
-
app: identity,
|
|
184
|
-
resources: () => ({}),
|
|
185
|
-
config: () => ({}),
|
|
186
|
-
services: () => ({}),
|
|
187
|
-
middlewares: (ctx) => {
|
|
188
|
-
// @ts-expect-error `env` 不存在于 MiddlewareContext
|
|
189
|
-
void ctx.env;
|
|
190
|
-
return [];
|
|
191
|
-
},
|
|
192
|
-
routers: () => undefined,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
/** #15 `services` 看不到 `env`(服务层禁读 env) */
|
|
196
|
-
export function servicesCannotSeeEnv() {
|
|
197
|
-
defineServer({
|
|
198
|
-
app: identity,
|
|
199
|
-
resources: () => ({}),
|
|
200
|
-
config: () => ({}),
|
|
201
|
-
services: (ctx) => {
|
|
202
|
-
// @ts-expect-error `env` 不存在于 ServiceContext
|
|
203
|
-
void ctx.env.DATABASE_URL;
|
|
204
|
-
return {};
|
|
205
|
-
},
|
|
206
|
-
middlewares: () => [],
|
|
207
|
-
routers: () => undefined,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"define-server.test.d.ts","sourceRoot":"","sources":["../../source/app/define-server.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { describe, expect, expectTypeOf, it } from 'vitest';
|
|
2
|
-
import { defineServer, isServer, SERVER_BRAND, generateOpenApi } from './entries.js';
|
|
3
|
-
/**
|
|
4
|
-
* `defineServer()`(N1 §1)——**纯定义**:产出一个 `Server` 对象,不建连、不起服务。
|
|
5
|
-
*
|
|
6
|
-
* 同一份定义可同时喂给「启动」与「出 spec」,这也是 `mode` 消失的原因。
|
|
7
|
-
*/
|
|
8
|
-
describe('defineServer 纯定义(N1 §1)', () => {
|
|
9
|
-
it('返回带品牌字段的 Server,并原样保留六个槽位', () => {
|
|
10
|
-
let resourcesCalls = 0;
|
|
11
|
-
const config = {
|
|
12
|
-
app: { service: 'define-server-test', title: 'Define Server Test', version: '1.0.0' },
|
|
13
|
-
resources: () => {
|
|
14
|
-
resourcesCalls += 1;
|
|
15
|
-
return {};
|
|
16
|
-
},
|
|
17
|
-
config: () => ({ enabled: true }),
|
|
18
|
-
services: () => ({}),
|
|
19
|
-
middlewares: () => [],
|
|
20
|
-
routers: () => undefined,
|
|
21
|
-
};
|
|
22
|
-
const server = defineServer(config);
|
|
23
|
-
expect(server.__brand).toBe(SERVER_BRAND);
|
|
24
|
-
expect(server.app).toEqual({ service: 'define-server-test', title: 'Define Server Test', version: '1.0.0' });
|
|
25
|
-
expect(server.services).toBe(config.services);
|
|
26
|
-
expect(server.routers).toBe(config.routers);
|
|
27
|
-
// 纯定义:不跑任何工厂
|
|
28
|
-
expect(resourcesCalls).toBe(0);
|
|
29
|
-
});
|
|
30
|
-
it('isServer 只识别 defineServer 产物', () => {
|
|
31
|
-
const server = defineServer({
|
|
32
|
-
app: { service: 'is-server-test', title: 'Is Server Test', version: '1.0.0' },
|
|
33
|
-
resources: () => ({}),
|
|
34
|
-
config: () => ({}),
|
|
35
|
-
services: () => ({}),
|
|
36
|
-
middlewares: () => [],
|
|
37
|
-
routers: () => undefined,
|
|
38
|
-
});
|
|
39
|
-
expect(isServer(server)).toBe(true);
|
|
40
|
-
expect(isServer({ __brand: 'other' })).toBe(false);
|
|
41
|
-
expect(isServer(null)).toBe(false);
|
|
42
|
-
expect(isServer('taicode.server')).toBe(false);
|
|
43
|
-
});
|
|
44
|
-
it('定义产物三入口共用:generateOpenApi 只读定义,不跑 config 槽位', async () => {
|
|
45
|
-
let configCalls = 0;
|
|
46
|
-
const server = defineServer({
|
|
47
|
-
app: { service: 'define-shared', title: 'Define Shared', version: '1.0.0' },
|
|
48
|
-
resources: () => ({}),
|
|
49
|
-
config: () => {
|
|
50
|
-
configCalls += 1;
|
|
51
|
-
return {};
|
|
52
|
-
},
|
|
53
|
-
services: () => ({}),
|
|
54
|
-
middlewares: () => [],
|
|
55
|
-
routers: () => undefined,
|
|
56
|
-
});
|
|
57
|
-
await generateOpenApi(server);
|
|
58
|
-
expect(configCalls).toBe(0);
|
|
59
|
-
});
|
|
60
|
-
it('app.version 必填:缺 version 时 TypeScript 编译失败(无默认值)', () => {
|
|
61
|
-
// 纯类型约束:这里只靠 `tsc --noEmit` 校验。若 `version` 又变回可选,
|
|
62
|
-
// `@ts-expect-error` 会因「未使用」而报错,测试反而变红。
|
|
63
|
-
const build = () => ({
|
|
64
|
-
// @ts-expect-error 缺少必填 app.version
|
|
65
|
-
app: { service: 'missing-version', title: 'Missing Version' },
|
|
66
|
-
resources: () => ({}),
|
|
67
|
-
config: () => ({}),
|
|
68
|
-
services: () => ({}),
|
|
69
|
-
middlewares: () => [],
|
|
70
|
-
routers: () => undefined,
|
|
71
|
-
});
|
|
72
|
-
expect(build).toBeTypeOf('function');
|
|
73
|
-
});
|
|
74
|
-
it('R / C / S 全推导:middlewares 与 routers 的 ctx.services 是强类型实体(M5)', () => {
|
|
75
|
-
defineServer({
|
|
76
|
-
app: { service: 'infer', title: 'Infer', version: '1.0.0' },
|
|
77
|
-
resources: () => ({ database: { query: (sql) => sql } }),
|
|
78
|
-
config: ({ resources }) => ({ domain: resources.database.query('domain') }),
|
|
79
|
-
services: ({ resources, config }) => ({
|
|
80
|
-
user: {
|
|
81
|
-
find: (id) => `${config.domain}:${resources.database.query(id)}`,
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
middlewares: (ctx) => {
|
|
85
|
-
// 类型自证:ctx.services 是 services 的返回类型(不是 unknown)
|
|
86
|
-
expectTypeOf(ctx.services.user.find).toEqualTypeOf();
|
|
87
|
-
// 类型自证:ctx.config 是 config 的返回类型
|
|
88
|
-
expectTypeOf(ctx.config.domain).toEqualTypeOf();
|
|
89
|
-
return [];
|
|
90
|
-
},
|
|
91
|
-
routers: (ctx) => {
|
|
92
|
-
expectTypeOf(ctx.services.user.find).toEqualTypeOf();
|
|
93
|
-
ctx.app.get('/user', () => ({ name: ctx.services.user.find('1') }));
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
});
|
package/output/app/entries.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { OpenApiDocument, Server, ServerConfig, StartServerOptions } from './types.js';
|
|
2
|
-
import type { FastifyInstance } from 'fastify';
|
|
3
|
-
export { SERVER_BRAND } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* `defineServer()`(N1 §1)——**纯定义**:产出一个 `Server` 对象,不建连、不起服务。
|
|
6
|
-
*
|
|
7
|
-
* 启动是另一个函数(`startServer`)的事——同一份定义可同时喂给「启动」与「出 spec」
|
|
8
|
-
* (`generateOpenApi`)。调用方**不写泛型**:`R` / `C` / `S` 全部从工厂返回类型推导。
|
|
9
|
-
*/
|
|
10
|
-
export declare function defineServer<R, C, S>(config: ServerConfig<R, C, S>): Server<R, C, S>;
|
|
11
|
-
/** 供内部/调试使用:判断是否为 `defineServer()` 产物 */
|
|
12
|
-
export declare function isServer(value: unknown): value is Server<unknown, unknown, unknown>;
|
|
13
|
-
/**
|
|
14
|
-
* `startServer()`——真正跑起来:构造资源、加载配置、建服务、装中间件、注册路由、listen、装信号。
|
|
15
|
-
*
|
|
16
|
-
* - 最早阶段**固定加载 env**(`.env.dev < .env < .env.local`;`ENV=test` 追加 `.env.test.local`)。
|
|
17
|
-
* - 返回**原生 `FastifyInstance`**:不包 `fastify-plugin`、不返回包装对象。
|
|
18
|
-
* - `listen` 默认 `NODE_ENV !== 'test'`(测试不监听)。
|
|
19
|
-
* - 硬性要求 `Server`(品牌)产物:传裸 `ServerConfig` 是编译错误。
|
|
20
|
-
*/
|
|
21
|
-
export declare function startServer<R, C, S>(server: Server<R, C, S>, options?: StartServerOptions<R, C, S>): Promise<FastifyInstance>;
|
|
22
|
-
/**
|
|
23
|
-
* `generateOpenApi()`——只出 spec,跑到能拿到 schema 就停。
|
|
24
|
-
*
|
|
25
|
-
* **红线**:全程**不得要求配置有效** —— 不跑 `config` 槽位、不要求 `DATABASE_URL` / `REDIS_URL`
|
|
26
|
-
* 有效;`resources`(只构造不建连)/ `services` / 中间件注册 / 路由注册照常执行。
|
|
27
|
-
*/
|
|
28
|
-
export declare function generateOpenApi<R, C, S>(server: Server<R, C, S>): Promise<OpenApiDocument>;
|
|
29
|
-
//# sourceMappingURL=entries.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../source/app/entries.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAMpF;AAED,yCAAyC;AACzC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAMnF;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,GAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAavI;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAiBhG"}
|
package/output/app/entries.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { bootServer, BOOT_PHASE_OPENAPI, BOOT_PHASE_START } from './boot.js';
|
|
2
|
-
import { loadRuntimeEnvFiles, resolveConfigEnv } from './env.js';
|
|
3
|
-
import { SERVER_BRAND } from './types.js';
|
|
4
|
-
export { SERVER_BRAND } from './types.js';
|
|
5
|
-
/**
|
|
6
|
-
* `defineServer()`(N1 §1)——**纯定义**:产出一个 `Server` 对象,不建连、不起服务。
|
|
7
|
-
*
|
|
8
|
-
* 启动是另一个函数(`startServer`)的事——同一份定义可同时喂给「启动」与「出 spec」
|
|
9
|
-
* (`generateOpenApi`)。调用方**不写泛型**:`R` / `C` / `S` 全部从工厂返回类型推导。
|
|
10
|
-
*/
|
|
11
|
-
export function defineServer(config) {
|
|
12
|
-
const server = {
|
|
13
|
-
...config,
|
|
14
|
-
__brand: SERVER_BRAND,
|
|
15
|
-
};
|
|
16
|
-
return server;
|
|
17
|
-
}
|
|
18
|
-
/** 供内部/调试使用:判断是否为 `defineServer()` 产物 */
|
|
19
|
-
export function isServer(value) {
|
|
20
|
-
return (typeof value === 'object' &&
|
|
21
|
-
value !== null &&
|
|
22
|
-
value.__brand === SERVER_BRAND);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* `startServer()`——真正跑起来:构造资源、加载配置、建服务、装中间件、注册路由、listen、装信号。
|
|
26
|
-
*
|
|
27
|
-
* - 最早阶段**固定加载 env**(`.env.dev < .env < .env.local`;`ENV=test` 追加 `.env.test.local`)。
|
|
28
|
-
* - 返回**原生 `FastifyInstance`**:不包 `fastify-plugin`、不返回包装对象。
|
|
29
|
-
* - `listen` 默认 `NODE_ENV !== 'test'`(测试不监听)。
|
|
30
|
-
* - 硬性要求 `Server`(品牌)产物:传裸 `ServerConfig` 是编译错误。
|
|
31
|
-
*/
|
|
32
|
-
export async function startServer(server, options = {}) {
|
|
33
|
-
const env = loadRuntimeEnvFiles();
|
|
34
|
-
const isTest = process.env.NODE_ENV === 'test';
|
|
35
|
-
const booted = await bootServer({
|
|
36
|
-
server,
|
|
37
|
-
env,
|
|
38
|
-
phase: BOOT_PHASE_START,
|
|
39
|
-
listen: options.listen ?? !isTest,
|
|
40
|
-
shutdown: options.shutdown,
|
|
41
|
-
});
|
|
42
|
-
return booted.app;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* `generateOpenApi()`——只出 spec,跑到能拿到 schema 就停。
|
|
46
|
-
*
|
|
47
|
-
* **红线**:全程**不得要求配置有效** —— 不跑 `config` 槽位、不要求 `DATABASE_URL` / `REDIS_URL`
|
|
48
|
-
* 有效;`resources`(只构造不建连)/ `services` / 中间件注册 / 路由注册照常执行。
|
|
49
|
-
*/
|
|
50
|
-
export async function generateOpenApi(server) {
|
|
51
|
-
// 不加载 .env 文件、不读配置
|
|
52
|
-
const env = resolveConfigEnv();
|
|
53
|
-
const booted = await bootServer({
|
|
54
|
-
server,
|
|
55
|
-
env,
|
|
56
|
-
phase: BOOT_PHASE_OPENAPI,
|
|
57
|
-
listen: false,
|
|
58
|
-
});
|
|
59
|
-
const app = booted.app;
|
|
60
|
-
if (typeof app.swagger !== 'function') {
|
|
61
|
-
throw new Error('[generateOpenApi] @fastify/swagger is not registered');
|
|
62
|
-
}
|
|
63
|
-
return app.swagger();
|
|
64
|
-
}
|