Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d81fa0b
workspace: Apply clippy auto-fixes across crates
Jul 30, 2026
ca8d949
core: Refactor diff markdown + fix shadowed binary patterns
Jul 30, 2026
e96ab36
core: Make Scalar matches exhaustive + use sort_by_key
Jul 30, 2026
8e796b6
ts/runtime: Convert file list to vec! macro + cleanup
Jul 30, 2026
9459aac
core: Collapse nested if-lets + extract test type aliases
Jul 30, 2026
845361a
emitters: Replace guarded chars().next().unwrap() with is_some_and
Jul 30, 2026
7322e67
core/diff: Expand golfed single-line functions for readability
Jul 30, 2026
92d31d5
core: Expand golfed functions in diff/security/graph
Jul 30, 2026
0dcec79
core/changelog: Gate test-only fn with cfg(test); expose example plugin
Jul 30, 2026
e714459
core: Document panics on built_in/generate_demo_spec/migration_guide
Jul 30, 2026
f40737c
core: Expand golfed Display impls + security analyzers
Jul 30, 2026
3bcbb8c
cli: Expand golfed analysis report printers
Jul 30, 2026
f5f6131
core: Expand golfed IR/Security helpers
Jul 30, 2026
61fb345
emitters: Escape + multiline-prefix doc comments from spec descriptions
Jul 31, 2026
59beed9
go emitter: Reserve built-in SDK type names to avoid model collisions
Jul 31, 2026
c745e52
rust emitter: Reserve built-in SDK type names for model collisions
Jul 31, 2026
0cab98d
examples: Regenerate petstore rust/go/ts SDKs with emitter fixes
Jul 31, 2026
80930a3
docs: CHANGELOG entry for doc-escaping + reserved-name fixes
Jul 31, 2026
061ca52
docs: Update README — fix stale version/test counts, commands, WASM t…
Jul 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [1.6.1] — 2026-07-30

### Fixed

#### Codegen (all emitters)
- **Doc-comment escaping** — schema/operation descriptions from real-world specs (GitHub, Stripe) contain embedded newlines, backticks, and `/*`/`*/` sequences that broke generated code: continuation lines lost their comment prefix (→ parse errors), `*/` closed block comments (→ "unterminated block comment"), and backticks tripped token errors. The Rust (`rust_doc`/`rust_doc_indented`) and Go (`go_doc`/`go_doc_label`) emitters now escape these and prefix every line. **Result: the 4 `*_generates_and_compiles_{rust,go}` regression tests for GitHub + Stripe specs now pass** (they were failing).
- **Reserved-name collisions** — a spec model whose name matches a built-in SDK type (e.g. GitHub's `ValidationError`) would redeclare it and break compilation. The Go and Rust emitters now suffix colliding model names with `Model`.

#### Rust emitter
- **Generated SDK now compiles** — fixed six template bugs that silently broke every generated Rust SDK since the interceptors/validation_middleware/ServiceContainer modules were added in 1.6.0: a response-interceptor loop nested inside the response-transformer loop; a missing `logger` field on `ClientBuilder`; telemetry call-site signature mismatches (`&Method`/`Duration` vs `&str`/`u128`); a two-arg `Result` used where the crate alias is one-arg; a `do_once` parameter-order mismatch; and `serde_json::to_vec` moving instead of borrowing. The example SDK was stale and never regenerated to catch this.
- **Generated README expanded** — `emit_readme` now documents interceptors, runtime validation (`validation_middleware`), and the `ServiceContainer` telemetry/DI helpers.

#### TypeScript emitter
- **Telemetry is now wired** — the `TelemetryHooks` interface and `MetricsCollector` were generated but never stored or invoked by `ApiClient`. The client now reads `opts.telemetry`/`container.telemetry` and calls `onRequestStart`/`onRequestEnd`/`onRequestError`/`onRetry`/`onCacheHit`/`onCacheMiss` at the right points in the request lifecycle.
- **Per-model validators typecheck** — generated object validators called `validateValue` with three arguments (missing the `errors` accumulator) and returned its `void` result as `ValidationError[]`. Now mirrors the enum-validator pattern.

#### Testing
- **Compile-the-generated-SDK regression tests** — added to the Rust (`cargo check`), TypeScript (`tsc --noEmit`), and Go (`go build ./...`) emitters. These regenerate the SDK into a temp crate and build it, so future emitter template breakage fails CI instead of shipping silently. All three emitters verified against both `fixtures/` specs (petstore + sample-api); each test skips cleanly only when its toolchain is genuinely absent.

---

## [1.6.0] — 2026-07-27

### Added
Expand Down Expand Up @@ -262,6 +283,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Version Links

- [v1.6.1](https://github.com/amafjarkasi/specforge-openapi-sdk-codegen/releases/tag/v1.6.1)
- [v1.6.0](https://github.com/amafjarkasi/specforge-openapi-sdk-codegen/releases/tag/v1.6.0)
- [v1.5.0](https://github.com/amafjarkasi/specforge-openapi-sdk-codegen/releases/tag/v1.5.0)
- [v1.4.0](https://github.com/amafjarkasi/specforge-openapi-sdk-codegen/releases/tag/v1.4.0)
Expand Down
62 changes: 39 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<a href="#quick-start"><img src="https://img.shields.io/badge/quick%20start-2%20min-f97316?style=for-the-badge&labelColor=1a0f0a" alt="Quick start"/></a>
<a href="#features"><img src="https://img.shields.io/badge/languages-TS%20%7C%20Go%20%7C%20Rust%20%7C%20WASM-ef4444?style=for-the-badge&labelColor=1a0f0a" alt="Languages"/></a>
<a href="#testing--ci"><img src="https://img.shields.io/badge/tests-unit%20%2B%20regression%20%2B%20e2e-fbbf24?style=for-the-badge&labelColor=1a0f0a" alt="Tests"/></a>
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-1.6.0-dc2626?style=for-the-badge&labelColor=1a0f0a" alt="Version"/></a>
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-1.6.1-dc2626?style=for-the-badge&labelColor=1a0f0a" alt="Version"/></a>
<a href="#license"><img src="https://img.shields.io/badge/license-MIT-fbbf24?style=for-the-badge&labelColor=1a0f0a" alt="License"/></a>
</p>

Expand Down Expand Up @@ -85,7 +85,7 @@ Each generated SDK is a standalone project — no shared runtime dependency, no

**5. Full IDE integration**

The [VS Code extension](vscode-extension/) provides 23 commands, auto-validation on save, context menus, keyboard shortcuts, and a status bar — everything you need to work with OpenAPI specs without leaving your editor.
The [VS Code extension](vscode-extension/) provides 24 commands, auto-validation on save, context menus, keyboard shortcuts, and a status bar — everything you need to work with OpenAPI specs without leaving your editor.

**6. Extensible via WASM plugins**

Expand Down Expand Up @@ -183,9 +183,9 @@ Every generated SDK is a **complete, production-ready client** — not just type
**WASM plugins**
- `specforge-plugin` crate with `Plugin` trait and `export_plugin!` macro
- Receives full IR as JSON, returns generated files
- Compile to `wasm32-wasi` for any language emitter
- Compile to `wasm32-wasip1` for any language emitter

### CLI subcommands (22 commands)
### CLI subcommands

| Command | What it does |
|---|---|
Expand All @@ -202,9 +202,8 @@ Every generated SDK is a **complete, production-ready client** — not just type
| `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 |
| `specforge dashboard` | Generate HTML metrics dashboard from SDK telemetry |
| `specforge security` | Analyze auth requirements and detect issues |
| `specforge graph` | Generate schema dependency diagrams (Mermaid/DOT) |
| `specforge profile` | Profile the performance of API endpoints from an OpenAPI spec |
| `specforge plugin` | Manage WASM emitter plugins |
| `specforge analyze` | Detect unused schemas, duplicates, optimization opportunities |
| `specforge mock` | Start a local mock server from spec examples |
| `specforge export` | Export Swagger Editor-compatible spec (inline `$ref`) |
Expand All @@ -219,11 +218,13 @@ Every generated SDK is a **complete, production-ready client** — not just type
| `specforge market add` | Add a spec to the marketplace |
| `specforge changelog` | Auto-generate CHANGELOG from spec changes |

> Run `specforge help` to see the full, current list — the CLI is the source of truth.

### Quality gates

- **227 unit tests** across core, emitters, and CLI
- **259 unit tests** across core, emitters, and CLI
- **21 test fixtures** (0.02MB to 14MB): petstore, GitHub, Stripe, Kubernetes, Atlassian, OpenAI, Vercel, Linode, Bitbucket, Adyen, Notion, Spotify, Adobe AEM, CircleCI, Okta, and more
- **Compile gates**: generated Go must `go build`, generated Rust must `cargo check`
- **Compile gates**: every emitter has a test that regenerates the SDK into a temp crate and compiles it — Go (`go build`), Rust (`cargo check`), TypeScript (`tsc --noEmit`). On top of that, `regression.rs` generates + compiles SDKs from real-world specs (GitHub ~9MB, Stripe ~7.6MB) in all three languages.
- **E2E smoke**: mock server × list/show/create + auth/retry/pagination (all 3 langs)
- **E2E advanced**: concurrency serialisation, dedupe single-flight, middleware rewrite, idempotency-key on POST, SSE parse (all 3 langs)
- **Performance benchmarks**: criterion benchmarks + 13 perf tests (petstore < 100ms, GitHub/Stripe < 10s)
Expand Down Expand Up @@ -632,7 +633,7 @@ sdk-ts/
├── README.md
└── src/
├── index.ts # createClient() + re-exports
├── client.ts # fetch core
├── client.ts # fetch core (ApiClient + retry/dedupe/telemetry)
├── auth.ts
├── retry.ts
├── paginate.ts
Expand All @@ -641,6 +642,14 @@ sdk-ts/
├── middleware.ts
├── idempotency.ts # Idempotency-Key generation
├── streaming.ts # streamBytes / streamLines / streamSse
├── cache.ts # ETag/conditional GET response cache
├── ratelimit.ts # token-bucket + sliding-window rate limiters
├── telemetry.ts # TelemetryHooks interface + MetricsCollector
├── logging.ts # pluggable Logger (ConsoleLogger)
├── interceptors.ts # request/response body interceptors
├── validate.ts # generated per-model validators
├── validation-middleware.ts # schema validation as middleware
├── service_container.ts # DI grouping (fetch/cache/logger/telemetry)
├── errors.ts # discriminated-union ApiError
├── models/<Name>.ts # one file per schema (+ oneOf guards)
└── api/<Tag>.ts # one class per tag
Expand Down Expand Up @@ -680,17 +689,24 @@ sdk-rs/
├── README.md
└── src/
├── lib.rs
├── client.rs # Client + ClientBuilder + request_stream
├── error.rs
├── retry.rs
├── paginate.rs
├── concurrency.rs
├── dedup.rs
├── middleware.rs
├── idempotency.rs
├── streaming.rs # SseStream
├── models.rs
└── api/<tag>.rs
├── api/ # one module per tag, one fn per operation
├── cache.rs # ETag/conditional GET response cache
├── client.rs # Client + ClientBuilder + ServiceContainer + request_stream
├── concurrency.rs # async in-flight semaphore
├── dedup.rs # coalesce identical in-flight safe requests
├── error.rs # typed Error enum
├── idempotency.rs # auto Idempotency-Key for safe retries
├── interceptors.rs # request/response body interceptors
├── logging.rs # pluggable Logger trait + Console/Noop impls
├── middleware.rs # request/response middleware chain
├── models.rs # one struct/enum per schema + validators
├── paginate.rs # cursor/offset pagination helpers
├── ratelimit.rs # token-bucket + sliding-window rate limiters
├── retry.rs # exponential backoff + jitter
├── streaming.rs # SseStream for server-sent events
├── telemetry.rs # TelemetryHooks trait + MetricsCollector
├── validate.rs # generated per-model validators
└── validation_middleware.rs # schema validation as middleware
```

</details>
Expand All @@ -706,7 +722,7 @@ plugin/
└── README.md
```

Build: `cargo build --target wasm32-wasi --release`
Build: `cargo build --target wasm32-wasip1 --release`

</details>

Expand Down Expand Up @@ -1039,7 +1055,7 @@ Commands: `generate`, `check`, `diff`, `emit`

The [specforge VS Code extension](vscode-extension/) provides a full IDE experience for working with OpenAPI specs:

**23 commands** accessible via `Ctrl+Shift+P`:
**24 commands** accessible via `Ctrl+Shift+P`:
- **Generate SDK** — Pick language, generate to output directory
- **Check Spec** — Validate with `--strict` mode
- **Diff Spec** — Compare two spec versions
Expand Down
Loading
Loading