Files
anomalyco_opencode/packages/httpapi-codegen/README.md
T
2026-06-22 16:48:04 -04:00

41 lines
3.0 KiB
Markdown

# @opencode-ai/httpapi-codegen
Build-time source generation for domain-oriented Effect APIs derived from `HttpApi` and Effect Schema contracts.
The package is private while its API is explored. Its tests are the executable specification for the generator. It must remain independent of OpenCode Core and use synthetic `HttpApi` fixtures.
## Settled rules
- Flatten path, query, header, and payload fields into one input object.
- Reject duplicate field names across input channels.
- Emit no method argument for zero fields, an optional object when every field is optional, and a required object when any field is required.
- Unwrap exact `{ data: A }` success envelopes.
- Map no-content success to `void`.
- Preserve other single success values.
- Reject ambiguous multiple-success contracts.
- Expose streaming success as `Stream`, not `Effect<Stream>`.
- Reject schemas whose wire/domain transformation cannot be generated exactly.
- Map transport, unexpected-status, and response-decoding failures to one stable generated `ClientError`.
- Generate only the Effect API initially; Promise runtime ownership, cancellation, and stream adaptation are deferred.
- Commit generated source for review; CI regenerates and fails when the worktree changes.
- Track generated files in `.httpapi-codegen.json` so regeneration removes only stale files previously owned by the generator.
## Boundary
This package generates only the remote API derived from `HttpApi`. It does not generate embedded implementations or embedded-only capabilities. The OpenCode integration composes two distinct total objects:
- A remote object containing the generated HTTP capabilities.
- An embedded object implementing the shared shape against local services and adding embedded-only capabilities.
The embedded object may be a structural superset of the remote object, but the constructors and concrete result types remain distinct.
Codegen generates every endpoint in the `HttpApi` it receives. OpenCode owns the product decision by composing the exact remote API before invoking the generator; the generic package has no endpoint filtering policy.
The public `generate(Api, { directory })` operation is an Effect requiring `FileSystem`. Internally it composes a pure `compile(Api)` phase with `write(output, directory)`. Compiler tests inspect virtual files directly; writer tests use `FileSystem.makeNoop`.
Generation formats TypeScript with Prettier before writing. Output paths are flat, unique, and checked against traversal, reserved manifest names, and existing symbolic links.
Generated source starts with one self-contained module per `HttpApiGroup`, plus root client and index modules. Schema dependencies may be duplicated across group modules. Cross-group schema partitioning is deferred until measured output or bundle cost requires it.
Codegen preserves group and endpoint identifiers exactly. The composed remote `HttpApi` owns public names such as `session` and `get`; the generator performs no prefix stripping, casing conversion, or public-name annotation mapping.