Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d819b74
feat: add native Rust codegen core for Bun
xban1x Aug 3, 2026
f8f2e96
perf: enable and tune native codegen for Node
xban1x Aug 3, 2026
e3d5d2e
perf: parallelize native code rendering
xban1x Aug 3, 2026
fc8a5b8
perf: accelerate native allocation and lookup paths
xban1x Aug 3, 2026
df31635
perf: remove native result JSON round trip
xban1x Aug 3, 2026
10bba62
perf: add native-complete generation fast path
xban1x Aug 3, 2026
214ed2c
perf: overlap Tiny OpenAPI preparation
xban1x Aug 4, 2026
a39c931
feat: support full native module-local generation
xban1x Aug 5, 2026
be543e0
fix: use trusted npm publishing client
xban1x Aug 5, 2026
e68e04c
feat: generate self-contained module clients
xban1x Aug 5, 2026
22c8055
fix: forward request config during prefetch
xban1x Aug 5, 2026
451a278
fix: initialize abilities during SSR
xban1x Aug 5, 2026
3616f3f
feat: add native fetch REST client
xban1x Aug 5, 2026
f36b24b
fix: import native client for upload hooks
xban1x Aug 5, 2026
8fd1d8d
feat: support native SSR fetch and retries
xban1x Aug 5, 2026
ff0d644
feat: add tree-shakeable ESM entry points
xban1x Aug 6, 2026
cd14a48
fix: circular type issue (#90)
urbankrepel-povio Aug 12, 2026
f1c0063
fix: render circular schema types in native codegen
xban1x Aug 15, 2026
cc50498
fix: preserve module model namespaces
xban1x Aug 15, 2026
49bec4b
fix: generate isolated module models
xban1x Aug 15, 2026
a22e5f3
fix: type module-local query helpers
xban1x Aug 15, 2026
e79c77e
feat: support domain error handling in native client
xban1x Aug 15, 2026
0ded3ab
Upgrade Zod and migrate to Bun
urbankrepel Sep 4, 2026
b9250e4
Merge remote-tracking branch 'origin/main' into codex/zod-4-5-bun
urbankrepel Sep 4, 2026
1da02e9
Avoid compiling circular Zod schemas
urbankrepel Sep 4, 2026
cd2f441
Merge 3.2 prerelease branch
urbankrepel Sep 4, 2026
201d1e5
Upgrade Bun to 1.4.1
urbankrepel Sep 7, 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
3 changes: 0 additions & 3 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@
* text=auto
* text eol=lf
*.zip binary
# GitHub Linguist Override
.yarn/* linguist-vendored
.pnp.js linguist-vendored
13 changes: 8 additions & 5 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ jobs:
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- run: corepack enable

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
cache: "pnpm"

- run: pnpm install --frozen-lockfile
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.1

- uses: dtolnay/rust-toolchain@stable

- run: bun install --frozen-lockfile

- run: pnpm check
- run: bun run check
59 changes: 32 additions & 27 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,55 @@ permissions:
contents: read

jobs:
build:
native:
strategy:
matrix:
os: [ubuntu-latest, macos-14, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.1
- uses: dtolnay/rust-toolchain@stable
- run: bun install --frozen-lockfile
- run: bun run build:native
- uses: actions/upload-artifact@v4
with:
name: native-${{ runner.os }}-${{ runner.arch }}
path: dist/*.node

publish:
needs: native
runs-on: ubuntu-latest
environment: v4
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3

- run: corepack enable

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: ".nvmrc"
cache: "pnpm"

- run: pnpm install --frozen-lockfile
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.1

- run: bun install --frozen-lockfile
- name: Set package version from tag
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
export VERSION

node <<'NODE'
const fs = require("fs");

const { VERSION: version } = process.env;

if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) {
throw new Error(`Invalid release version: ${version}`);
}

const packageJsonPath = "package.json";
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));

packageJson.version = version;
fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
NODE

- run: pnpm build

bun -e 'const packageJson = await Bun.file("package.json").json(); packageJson.version = process.env.VERSION; await Bun.write("package.json", `${JSON.stringify(packageJson, null, 2)}\n`);'
- run: bun run build:ts
- uses: actions/download-artifact@v4
with:
pattern: native-*
path: dist
merge-multiple: true
- run: npm pack

- name: Publish release
if: "!contains(github.ref, '-rc.')"
run: npm publish --access=public

- name: Publish release candidate
if: contains(github.ref, '-rc.')
run: npm publish --access=public --tag next
8 changes: 0 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
# yarn
.yarn/*
#!.yarn/cache
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks

/output
/dist

Expand Down
2 changes: 1 addition & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"ignorePatterns": ["**/*.hbs", "node_modules", ".yarn", "test/generated/**"]
"ignorePatterns": ["**/*.hbs", "node_modules", "test/generated/**"]
}
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bun 1.4.1
78 changes: 63 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ The tool partially leverages code from [openapi-zod-client](https://github.com/a
## Setup

```bash
yarn add @povio/openapi-codegen-cli
bun add @povio/openapi-codegen-cli
```

## Example

```bash
yarn openapi-codegen generate --input http://localhost:3001/docs-json
bunx openapi-codegen generate --input http://localhost:3001/docs-json
```

## Configuration Files
Expand All @@ -46,7 +46,7 @@ export default config;
Then run without arguments:

```bash
yarn openapi-codegen generate
bunx openapi-codegen generate
```

### Configuration File Discovery
Expand All @@ -58,7 +58,7 @@ The CLI automatically searches for the TypeScript configuration file:
You can also specify a custom configuration file:

```bash
yarn openapi-codegen generate --config my-config.ts
bunx openapi-codegen generate --config my-config.ts
```

## Options
Expand Down Expand Up @@ -89,7 +89,8 @@ yarn openapi-codegen generate --config my-config.ts
--modelsInCommon Keep all schema declarations in defaultTag models and emit per-module proxy exports (default: false)
--replaceOptionalWithNullish Replace `.optional()` chains with `.nullish()` in generated Zod schemas (default: false)

--axiosRequestConfig Include Axios request config parameters in query hooks (default: false)
--restClient REST transport to generate: 'axios' or 'native' (default: 'axios')
--axiosRequestConfig Include transport request config parameters in query hooks (default: false)
--infiniteQueries Generate infinite queries for paginated API endpoints (default: false)
--mutationEffects Add mutation effects options to mutation hooks (default: true)
--mutationScope Serialize mutations for the same path-param resource via TanStack scope.id (default: false).
Expand Down Expand Up @@ -132,29 +133,76 @@ yarn openapi-codegen generate --config my-config.ts
#### Test locally

```bash
# prerequisites
corepack install
yarn
# install dependencies
bun install

# run tests
yarn test
bun run test

# run sources with tsx
yarn start --help
yarn start generate --input ./test/petstore.yaml --verbose
# run TypeScript sources directly with Bun
bun run start --help
bun run start generate --input ./test/petstore.yaml --verbose

# build new version
yarn build
bun run build

# test build
yarn start --help
yarn start:dist generate --input ./test/petstore.yaml --verbose
bun run start --help
bun run start:dist generate --input ./test/petstore.yaml --verbose
```

### Native Bun code generation

The Bun and Node.js CLIs and the Vite plugin automatically use the bundled Rust code-generation core when a compatible native binary is available. Generated files remain byte-for-byte compatible with the TypeScript implementation, which is retained as the fallback when the addon cannot be loaded.

Set `OPENAPI_CODEGEN_NATIVE=0` to force the TypeScript path, or `OPENAPI_CODEGEN_NATIVE=1` to require the native path and fail when its binary is unavailable.

Release packages include native binaries for Linux x64, macOS arm64, and Windows x64. Build a binary for the current platform with `bun run build:native`.

## Common Issues

### App REST Client Interceptors

Select the fetch-based client without changing endpoint and query APIs:

```ts
import type { OpenAPICodegenConfig } from "@povio/openapi-codegen-cli";

export default {
restClient: "native",
} satisfies OpenAPICodegenConfig;
```

Native mode imports common request/response contracts from `@povio/openapi-codegen-cli/rest` and the concrete
`NativeRestClient` from `@povio/openapi-codegen-cli/native`. It uses `fetch` for normal requests and uploads, switching
to `XMLHttpRequest` in browsers only when an upload progress callback is provided.

Native interceptors use the common transport interface:

```ts
import { NativeRestClient } from "@povio/openapi-codegen-cli/native";
import type { RestTransportInterceptor } from "@povio/openapi-codegen-cli/rest";

const authorizationInterceptor: RestTransportInterceptor = {
onRequest(request) {
request.headers.set("Authorization", `Bearer ${localStorage.getItem("accessToken")}`);
return request;
},
};

export const AppRestClient = new NativeRestClient({
config: { baseURL: "https://api.example.com" },
interceptors: [authorizationInterceptor],
});
```

Axios remains the default for backward compatibility. The existing Axios interceptor API remains available in Axios
mode.

Native mode does not run the library `ErrorHandler` or create `ApplicationException` values. It throws `HttpError` for
non-success HTTP responses and preserves Zod, network, cancellation, and timeout errors so applications can handle them
directly in query callbacks, error boundaries, or their own normalization layer.

In order to add interceptors to the used REST client, you must create your own instance of a RestClient and pass your implemented interceptors into the constructor. Make sure to set `restClientImportPath` in your openapi generation configuration too.

```ts
Expand Down
Loading
Loading