@supacloud/compiler 0.17.0 → 0.19.1
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/README.md +166 -7
- package/dist/cli.js +8711 -9465
- package/dist/config.d.ts +5 -1
- package/dist/generate.d.ts +13 -2
- package/dist/index.d.ts +7 -3
- package/dist/index.js +7863 -8711
- package/dist/migrations.d.ts +41 -0
- package/dist/openapi-tools.d.ts +41 -0
- package/dist/route-contracts.d.ts +2 -2
- package/dist/type-safety.d.ts +26 -0
- package/dist/types.d.ts +57 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Local Delivery
|
|
4
4
|
|
|
5
|
-
`supacloud-compiler plan --json` previews workload targets
|
|
5
|
+
`supacloud-compiler plan --json` previews workload targets, dependency closures,
|
|
6
|
+
route ownership, and required runtime capabilities without writing or deploying.
|
|
6
7
|
`supacloud-compiler build-delivery --json` creates independent local factory bundles
|
|
7
8
|
and an atomic inspection manifest, reusing unchanged artifacts without deployment.
|
|
8
|
-
See [local delivery](./DELIVERY.md) for configuration,
|
|
9
|
+
See [local delivery](./DELIVERY.md) for validated configuration, AI-facing
|
|
10
|
+
contracts, and the distinction between a topology preview and release evidence.
|
|
9
11
|
|
|
10
12
|
## Persistent Execution Policy
|
|
11
13
|
|
|
@@ -20,6 +22,37 @@ recovery suggestions and participate in JSON output and the existing no-write-on
|
|
|
20
22
|
gate. These checks validate declared policy, not the implementation of a custom
|
|
21
23
|
adapter. See [configuration and migration](../../docs/command-migration.md).
|
|
22
24
|
|
|
25
|
+
## Source Migrations
|
|
26
|
+
|
|
27
|
+
The compiler includes deterministic, versioned source migrations for breaking
|
|
28
|
+
framework changes. The command is preview-only unless `--write` is explicit:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Preview files, replacements, and manual conflicts
|
|
32
|
+
bunx supacloud-compiler migrate --root . --json
|
|
33
|
+
|
|
34
|
+
# Apply only after reviewing the preview
|
|
35
|
+
bunx supacloud-compiler migrate --root . --write
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Migrations operate on TypeScript ASTs and skip `node_modules`, `dist`, and
|
|
39
|
+
`generated`. Route options are resolved through local constants,
|
|
40
|
+
`defineRouteContract(...)`, namespace properties, named imports, and the
|
|
41
|
+
project's `tsconfig` path/module settings, so a shared contract declaration is
|
|
42
|
+
changed once even when several controllers import it. If the contract is outside
|
|
43
|
+
the selected root/include set, or any file has an ambiguous transformation, the
|
|
44
|
+
command exits non-zero and writes no file. A successful write uses a
|
|
45
|
+
same-directory temporary file followed by replacement for each changed file; it
|
|
46
|
+
is not a version-control rollback mechanism. Review the diff, then run `compile`,
|
|
47
|
+
`check`, and focused tests with the same compiler version. Use version control to
|
|
48
|
+
revert a migration.
|
|
49
|
+
|
|
50
|
+
The current route-contract migration is `route-response-to-responses` (`0.11.0`
|
|
51
|
+
to `0.12.0`): it changes `response: Schema` into
|
|
52
|
+
`responses: { 200: Schema }`. It refuses to guess when `responses` is already
|
|
53
|
+
present. See the [route contract migration guide](../../docs/route-contract-migration.md)
|
|
54
|
+
for the complete upgrade and release sequence.
|
|
55
|
+
|
|
23
56
|
FA-derived direct-command RPC ownership, contract inspection and POST command
|
|
24
57
|
protocol migration are documented in `docs/fa-consumer-governance.md` in the
|
|
25
58
|
repository. `context <module> --json` reports `routeContracts` and standalone
|
|
@@ -211,6 +244,7 @@ bunx supacloud-compiler dev
|
|
|
211
244
|
| 文件发现 | `**/*.module.ts`、`**/*.ts` |
|
|
212
245
|
| strict 类型安全门 | 开启 |
|
|
213
246
|
| typed client | 开启 |
|
|
247
|
+
| OpenAPI 3.1 module | 开启 |
|
|
214
248
|
| permissions manifest | 开启 |
|
|
215
249
|
| module boundary preset | `modular-monolith` |
|
|
216
250
|
| provider tree-shaking | 开启 |
|
|
@@ -225,6 +259,11 @@ export default defineSupacloudConfig({
|
|
|
225
259
|
outDir: "generated",
|
|
226
260
|
strict: true,
|
|
227
261
|
generateClient: true,
|
|
262
|
+
generateOpenApi: true,
|
|
263
|
+
openApi: {
|
|
264
|
+
title: "Orders API",
|
|
265
|
+
version: "1.0.0",
|
|
266
|
+
},
|
|
228
267
|
generatePermissions: true,
|
|
229
268
|
moduleBoundaryPreset: "modular-monolith",
|
|
230
269
|
commandCapabilities: {
|
|
@@ -241,6 +280,37 @@ export default defineSupacloudConfig({
|
|
|
241
280
|
`commandCapabilities` 用于声明运行时实际支持的命令治理能力;命令声明了
|
|
242
281
|
`permission`、`audit` 或 `idempotency` 时,若对应能力关闭,编译器会失败。
|
|
243
282
|
|
|
283
|
+
## OpenAPI 与 Client Generator
|
|
284
|
+
|
|
285
|
+
编译器从同一份 `ApplicationGraph` 生成 `client.ts` 和 `openapi.ts`,不引入
|
|
286
|
+
反射或第二套路由注册。路由装饰器中显式声明的 TypeBox `body`、`params`、
|
|
287
|
+
`query`、`response` schema 会被静态导入;没有 schema 的字段保持为
|
|
288
|
+
`unknown`,不会从 TypeScript 类型推断出未经验证的运行时协议。
|
|
289
|
+
|
|
290
|
+
`client.ts` 提供路由方法、路径参数检查、请求类型和 `API_ROUTES`。已声明
|
|
291
|
+
响应 schema 的方法不传 decoder 也会按 HTTP status 自动选择并校验内置 schema;
|
|
292
|
+
传入 `ResponseDecoder<T>` 时,decoder 接收已经通过 schema 校验/规范化的值,
|
|
293
|
+
可安全做日期、金额等业务转换。没有响应 schema 的方法仍返回原始 `unknown`,
|
|
294
|
+
除非调用方显式提供 decoder。
|
|
295
|
+
|
|
296
|
+
`openapi.ts` 导出 `OPENAPI_DOCUMENT`、`OPENAPI_JSON` 和
|
|
297
|
+
`createOpenApiDocument()`。它包含 OpenAPI 3.1 路径、参数、请求体、响应、
|
|
298
|
+
错误协议、默认 bearer security scheme,以及 `x-supacloud` 中的模块、命令、
|
|
299
|
+
权限和静态 contract 元数据。文档只描述编译器发现的 HTTP routes;文件和
|
|
300
|
+
流式响应仍由宿主运行时负责传输。
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# 导出可提交或交给文档工具的 JSON
|
|
304
|
+
bunx supacloud-compiler openapi-export generated/openapi.ts openapi.json
|
|
305
|
+
|
|
306
|
+
# 在 CI 中阻止破坏性 contract 变更
|
|
307
|
+
bunx supacloud-compiler openapi-diff openapi-baseline.json openapi.json --json
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`openapi-diff` 会检查路径/操作、参数必填性、请求体、响应状态和 schema 的
|
|
311
|
+
枚举、属性与 required 变化;命令失败时返回非零退出码。基线文件由应用
|
|
312
|
+
负责版本管理,生成的 `openapi.ts` 则由普通 `compile`/`check` 漂移检查维护。
|
|
313
|
+
|
|
244
314
|
## API
|
|
245
315
|
|
|
246
316
|
```ts
|
|
@@ -339,9 +409,88 @@ IDE 和 AI agent 做状态机漂移检查。
|
|
|
339
409
|
- AOP 只支持静态边界:`ModuleOptions.aspects`、`RouteOptions.aspects`、`CommandOptions.aspects` 和 `JobOptions.aspects` 必须是显式数组字面量,元素必须是可解析的函数标识符。生成器会直接 import aspect 并生成固定顺序的 onion chain,不使用 Proxy、Reflect 扫描、动态 pointcut 或运行时注册。
|
|
340
410
|
- 执行顺序为 `module -> route -> command -> commandGovernance -> handler`;Job 使用 `module -> job -> executor -> run/execute`,并在 finally 中销毁 job scope。
|
|
341
411
|
- services 对象的 key 为 token 名的 camelCase:`CaseService → caseService`、`CASE_REPOSITORY → caseRepository`、`LOGGER → logger`。
|
|
342
|
-
- controller 描述静态给出:`{ path, serviceKey, scope, routes: [{ method, path, handler, body?, params?, query?, response? }] }`,schema 直接引用 import 进来的对象。
|
|
412
|
+
- controller 描述静态给出:`{ path, serviceKey, scope, routes: [{ method, path, handler, body?, params?, query?, headers?, cookie?, response?, responses? }] }`,schema 直接引用 import 进来的对象。
|
|
413
|
+
- `client.ts` 在启用 `generateClient` 时生成:包含 `API_ROUTES`、`API_SCHEMAS`、类型化请求选项和显式响应 decoder 入口。
|
|
414
|
+
- `openapi.ts` 在启用 `generateOpenApi` 时生成:包含 OpenAPI 3.1 文档模块和可序列化 JSON;`check` 会将它纳入生成物漂移检查。
|
|
343
415
|
- 严格生成模式会对 `application.ts`、可选的 `client.ts` 和 `permissions.ts` 做 AST 扫描,禁止生成 `any`。
|
|
344
416
|
|
|
417
|
+
`<outDir>/client.ts` 提供按 Controller 分组的 Fetch client。路径参数会从
|
|
418
|
+
controller 和 route 的完整路径合并推导;声明了 `response` 或 `responses` 的
|
|
419
|
+
route 会自动按 HTTP status 执行内置 response decoder,并返回 schema 推导的
|
|
420
|
+
类型。显式 decoder 仍可用于覆盖自定义转换;没有响应 schema 的 route 返回
|
|
421
|
+
`unknown`。`headers`、`cookie` 和多状态 `responses` 会同步进入客户端和
|
|
422
|
+
OpenAPI。`buildRouteUrl` 和 `createApiClient` 可直接复用,也支持动态 headers
|
|
423
|
+
和请求拦截器。
|
|
424
|
+
|
|
425
|
+
### Migration from manual decoders
|
|
426
|
+
|
|
427
|
+
旧版本要求调用方为每个有响应 schema 的 route 传入 decoder。升级后删除该
|
|
428
|
+
decoder 即可;需要保留自定义转换时,将它作为第二个参数传入。旧的单一
|
|
429
|
+
`response: Schema` 当前作为迁移桥接仍可编译,但新代码必须迁移到
|
|
430
|
+
`responses: { 200: Schema }` 或实际的状态映射;该桥接字段不保证在下一次破坏性
|
|
431
|
+
版本继续保留。Management API 的契约注册表
|
|
432
|
+
由实际 Elysia `app.routes` 投影生成,不应再维护平行的路由清单。
|
|
433
|
+
|
|
434
|
+
完整的破坏性升级步骤(包括 headers、cookie、客户端 decoder、OpenAPI 和生成物
|
|
435
|
+
刷新)见 [route contract migration guide](../../docs/route-contract-migration.md)。
|
|
436
|
+
|
|
437
|
+
`<outDir>/openapi.ts` 是无额外运行时依赖的 OpenAPI 3.1 module,导出
|
|
438
|
+
`OPENAPI_DOCUMENT`、`OPENAPI_JSON`、`createOpenApiDocument` 和
|
|
439
|
+
`serializeOpenApiDocument`。它在运行时读取同一组 TypeBox schema,生成 paths、
|
|
440
|
+
parameters、requestBody、responses、securitySchemes 以及 `x-supacloud` 路由元数据,
|
|
441
|
+
因此不会维护第二份 API contract。默认包含 bearer JWT scheme;项目可在
|
|
442
|
+
`openApi` 配置中补充文档信息、servers 和其他显式 security schemes。
|
|
443
|
+
|
|
444
|
+
`OPENAPI_JSON` 是运行时快照;需要提交独立 `openapi.json` 时,在应用已经能加载
|
|
445
|
+
生成模块的运行时调用 `exportGeneratedOpenApiJson()` 或直接写出该字符串。编译器
|
|
446
|
+
不会为了生成 JSON 执行应用 schema。`readOpenApiJson()` 和
|
|
447
|
+
`diffOpenApiDocuments()` 可用于构建发布门禁:
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
import {
|
|
451
|
+
exportGeneratedOpenApiJson,
|
|
452
|
+
diffOpenApiDocuments,
|
|
453
|
+
readOpenApiJson,
|
|
454
|
+
} from "@supacloud/compiler";
|
|
455
|
+
|
|
456
|
+
await exportGeneratedOpenApiJson({
|
|
457
|
+
modulePath: "./generated/openapi.ts",
|
|
458
|
+
outputPath: "./generated/openapi.json",
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
const diff = diffOpenApiDocuments(
|
|
462
|
+
await readOpenApiJson("./contracts/openapi.base.json"),
|
|
463
|
+
await readOpenApiJson("./generated/openapi.json"),
|
|
464
|
+
);
|
|
465
|
+
if (!diff.ok) throw new Error("OpenAPI breaking change");
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
也可以直接在 CI 中运行:
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
supacloud-compiler openapi-export ./generated/openapi.ts ./generated/openapi.json
|
|
472
|
+
supacloud-compiler openapi-diff ./contracts/openapi.base.json ./generated/openapi.json --json
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
`openapi-export` 在运行时加载生成的 `openapi.ts` 并原子地写出独立 JSON;它不会在
|
|
476
|
+
编译阶段执行应用 schema。可用 `--space 0` 到 `--space 10` 控制缩进,重复执行不会
|
|
477
|
+
改写内容不变的文件。当前只承诺 JSON 输出,YAML 转换由发布流水线按需处理。
|
|
478
|
+
|
|
479
|
+
diff 默认阻止路径/操作/参数/响应删除、请求约束收紧、响应字段收窄或安全要求新增;
|
|
480
|
+
新增可选参数、路径、响应和组件会标记为 non-breaking。它是保守的合同门禁,不替代
|
|
481
|
+
应用端的业务兼容性测试。
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
export default defineSupacloudConfig({
|
|
485
|
+
generateClient: true,
|
|
486
|
+
generateOpenApi: true,
|
|
487
|
+
openApi: { title: "Orders API", version: "1.0.0" },
|
|
488
|
+
});
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
用 `--no-client` 或 `--no-openapi` 关闭对应产物;`compile` 和 `check` 会同时检查
|
|
492
|
+
已生成的 `client.ts`、`openapi.ts` 是否与当前 ApplicationGraph 漂移。
|
|
493
|
+
|
|
345
494
|
`<outDir>/app.manifest.json`:`{ version: 1, modules, externalTokens }`,供 CLI graph/explain 使用。
|
|
346
495
|
|
|
347
496
|
## 诊断码
|
|
@@ -452,8 +601,8 @@ bun run build
|
|
|
452
601
|
|
|
453
602
|
## Route Contract Policy
|
|
454
603
|
|
|
455
|
-
|
|
456
|
-
`CompileOptions` to report `route-contract-required` errors in both compile and
|
|
604
|
+
Project configuration defaults to `requireRouteContracts: true`. Low-level
|
|
605
|
+
`CompileOptions` callers can set it explicitly to report `route-contract-required` errors in both compile and
|
|
457
606
|
check (including JSON diagnostics). Changing this option invalidates incremental
|
|
458
607
|
results. Combine it with `writeOnError: false` when programmatic compilation must
|
|
459
608
|
not emit files on errors.
|
|
@@ -463,10 +612,20 @@ query, and response declarations. Required inputs are detected from handler
|
|
|
463
612
|
bindings and controller/route path parameters. Responses always require an
|
|
464
613
|
explicit declaration, including intentional void contracts.
|
|
465
614
|
|
|
466
|
-
This checks declaration coverage
|
|
615
|
+
This checks declaration coverage and rejects known opaque schemas, not full schema quality, handler/schema type
|
|
467
616
|
equivalence, or database authorization. It deliberately does not auto-fix missing
|
|
468
617
|
schemas with `unknown` placeholders. Consumers must define the actual contracts
|
|
469
|
-
and test decoding separately.
|
|
618
|
+
and test decoding separately. Native output must be classified; delegated
|
|
619
|
+
validation and native transports require a `contract.evidence` test reference.
|
|
620
|
+
The report still sets `verified: false`, since a reference does not prove execution.
|
|
621
|
+
|
|
622
|
+
The source type gate now includes TypeScript syntactic/semantic diagnostics and
|
|
623
|
+
rejects production `@ts-ignore`, `@ts-nocheck` and `@ts-expect-error`. A source-directory root resolves
|
|
624
|
+
the enclosing tsconfig. When this gate is enabled, incremental compilation
|
|
625
|
+
rechecks types instead of returning an unchecked cached result.
|
|
626
|
+
|
|
627
|
+
Generated route calls require all path parameters and a decoder for typed
|
|
628
|
+
responses. See [type safety and migration](../../docs/type-safety.md).
|
|
470
629
|
|
|
471
630
|
## License
|
|
472
631
|
|