diff --git a/README.md b/README.md index 216fda9..813f6ba 100644 --- a/README.md +++ b/README.md @@ -199,6 +199,7 @@ Every generated SDK is a **complete, production-ready client** — not just type | `specforge migrate` | Generate a migration guide between two spec versions | | `specforge docs` | Generate a static HTML API documentation site | | `specforge test` | Generate mock server tests from spec examples | +| `specforge version` | Apply API versioning (URL/header/query) to a spec's endpoints | | `specforge versions` | List API versions in a spec directory | | `specforge workspace` | Generate SDKs for all specs in a workspace config | | `specforge workspace-init` | Generate a workspace config from a directory | @@ -305,8 +306,12 @@ cargo build -p specforge-cli TypeScript ```ts -import { createClient, bearerAuth, streamSse } from "./sdk-ts/src/index.ts"; +import { createClient, bearerAuth } from "./sdk-ts/src/index.ts"; +import { ApiClient } from "./sdk-ts/src/client"; +import { streamSse } from "./sdk-ts/src/streaming"; +// `bearerAuth` / `apiKeyAuth` are emitted only when the spec declares those +// security schemes. Specs with no security emit `anonymousAuth` instead. const client = createClient({ baseUrl: "https://api.example.com", auth: bearerAuth(() => process.env.API_TOKEN!), @@ -318,13 +323,16 @@ const client = createClient({ const page = await client.pets.listPets({ limit: 20 }); -// Streaming (SSE) -const res = await client.request("GET", "/events"); +// Streaming (SSE) — request() lives on the underlying ApiClient. +const api = new ApiClient({ baseUrl: "https://api.example.com" }); +const res = await api.request("GET", "/events"); for await (const ev of streamSse(res)) { console.log(ev.event, ev.data); } ``` +> `createClient()` returns a tree-shakeable tag namespace (`client.pets.listPets`). For raw requests / streaming, use the `ApiClient` directly. The auth helpers (`bearerAuth`, `apiKeyAuth`) appear only when your spec declares those schemes. +
@@ -394,24 +402,14 @@ while let Some(ev) = sse.next_event().await? { ## CLI reference +Run `specforge --help` for the full, current command list (the CLI is the source of truth — see the table above). The most-used commands: + ```text -specforge - -Commands: - generate Generate an SDK from an OpenAPI spec - check Lint and validate an OpenAPI spec without generating - diff Compare two OpenAPI specs and report breaking changes - emit Emit the resolved IR as JSON (for external emitters / plugins) - init Scaffold a new minimal OpenAPI spec - convert Convert between OpenAPI 3.0 and 3.1 - merge Merge multiple OpenAPI spec files into one - migrate Generate a migration guide between two spec versions - docs Generate static HTML API documentation - test Generate mock server tests for generated SDKs - versions List API versions in a spec directory - workspace Generate SDKs for all specs in a workspace config - workspace-init Generate a workspace config from a directory - help Print this message or the help of the given subcommand +specforge generate # Generate an SDK (the main command) +specforge check # Lint a spec (--strict = warnings as errors) +specforge diff # Breaking-change detection (exit 1 on breaking) +specforge emit # Dump resolved IR as JSON (for external emitters) +specforge --help # Per-command flags ``` ### `specforge generate` @@ -423,16 +421,23 @@ Arguments: Path to OpenAPI YAML or JSON Options: - -o, --out Output directory [default: ./generated] - -l, --lang ts | go | rust [default: ts] - -n, --name Package / module / crate name override - --version API version (when spec is a directory) - --profile Output timing breakdown for each pipeline stage - -v, --log-level error|warn|info|debug|trace [default: info] + -o, --out Output directory [default: ./generated] + -l, --lang ts | go | rust [default: ts] + -n, --name Package / module / crate name override + --version API version (when spec is a directory) + --profile Output timing breakdown for each pipeline stage + --include-webhooks Emit webhook handler types (OpenAPI 3.1) + --locale Comma-separated locale codes for i18n errors (e.g. en,es) + --changelog Auto-generate CHANGELOG.md in the output dir + --changelog-previous Previous spec to diff against (use with --changelog) + --version-prefix Apply a URL path versioning prefix (e.g. v1) + --plugin Use a WASM plugin emitter by name + -v, --log-level error|warn|info|debug|trace [default: info] -h, --help - -V, --version ``` +> `-V, --version` is a top-level flag (`specforge -V`), not a `generate` option. + | Language | `-n` means | Default if omitted | |----------|------------|--------------------| | **ts** | npm package name in `package.json` | `@sdk` | @@ -449,6 +454,11 @@ Arguments: Options: --strict Treat warnings as errors + --deprecations List deprecated operations and schemas + --disable Disable a lint rule (repeatable) + --enable Enable a lint rule (repeatable) + --severity Set rule severity: error|warning|off (repeatable) + --config Path to a lint config YAML file (.specforge.yaml) -v, --log-level error|warn|info|debug|trace [default: info] ``` @@ -869,8 +879,8 @@ See **[RELEASE.md](./RELEASE.md)** for the full checklist. Short version: # 2. update CHANGELOG.md ./scripts/ci.sh full ./scripts/generate-examples.sh -git tag -a v0.1.0 -m "specforge v0.1.0" -git push origin v0.1.0 +git tag -a v1.6.1 -m "specforge v1.6.1" +git push origin v1.6.1 ``` Binary: `cargo build --release -p specforge-cli` → `target/release/specforge`. @@ -889,6 +899,20 @@ Binary: `cargo build --release -p specforge-cli` → `target/release/specforge`. ## Status & roadmap +**v1.6.1** — codegen robustness + readability cleanup: + +- [x] Doc-comment escaping (Rust + Go emitters) — real-world specs (GitHub, Stripe) with backticks, `/*`/`*/`, and multi-paragraph descriptions no longer break generated code +- [x] Reserved-name collision protection (Go + Rust) — spec models named like built-in SDK types (`ValidationError`, etc.) get a `Model` suffix +- [x] Per-emitter compile gates — generated SDKs are regenerated into a temp crate and compiled (`cargo check` / `go build` / `tsc --noEmit`) in CI +- [x] Regression tests now cover GitHub (~9MB) + Stripe (~7.6MB) specs in Rust + Go — 4 previously-failing tests now pass +- [x] **259 tests** passing; clippy warnings 120 → 2 + +**v1.6.0** — compile-gate tests + telemetry/validation middleware: + +- [x] `ServiceContainer` DI, `RequestInterceptor`/`ResponseInterceptor`, response transformers +- [x] Validation middleware (`validation_middleware.rs`) wired into all emitters +- [x] Telemetry hooks wired into the TypeScript client + **v1.5.0** — web UI redesign, spec marketplace: - [x] Professional light theme — complete rewrite (1713 lines, design system) @@ -1030,7 +1054,7 @@ Binary: `cargo build --release -p specforge-cli` → `target/release/specforge`. - [x] Multi-platform CI (Linux, macOS, Windows) - [x] Richer generated READMEs (errors, pagination, concurrency, middleware, streaming) -**All roadmap items completed through v1.5.0. Production-ready with professional web UI and marketplace.** +**All roadmap items completed through v1.6.1. Production-ready: real-world specs (GitHub, Stripe) generate + compile in all languages, with per-emitter compile gates in CI.** --- @@ -1041,7 +1065,7 @@ Binary: `cargo build --release -p specforge-cli` → `target/release/specforge`. Use specforge in CI with the official GitHub Action: ```yaml -- uses: amafjarkasi/specforge-openapi-sdk-codegen@v0.2.2 +- uses: amafjarkasi/specforge-openapi-sdk-codegen@v1 with: command: generate spec: openapi.yaml @@ -1049,7 +1073,7 @@ Use specforge in CI with the official GitHub Action: output: ./sdk ``` -Commands: `generate`, `check`, `diff`, `emit` +Commands: `generate`, `check`, `diff`, `emit`. Pin to a major version (`@v1`) for non-breaking updates, or a specific tag (`@v1.0.0`) for reproducibility. ### VS Code Extension