@bazo/openapi-client-generator 3.0.13

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/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@bazo/openapi-client-generator",
3
+ "version": "3.0.13",
4
+ "bin": {
5
+ "openapi-client-generator": "bin.js"
6
+ },
7
+ "files": [
8
+ "bin.js",
9
+ "skills"
10
+ ],
11
+ "dependencies": {
12
+ "@apidevtools/swagger-parser": "^12.1.0"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/bazo/openapi-client-generator.git"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public",
20
+ "registry": "https://registry.npmjs.org"
21
+ }
22
+ }
@@ -0,0 +1,180 @@
1
+ ---
2
+ name: generate-client
3
+ description: >
4
+ Run the @bazo/openapi-client-generator CLI to produce a typed API client
5
+ from an OpenAPI JSON spec. Covers CLI flags (-n/--name, -m/--mode),
6
+ positional arguments (spec path, output directory), generation modes
7
+ (full, playwright, swift, kotlin), output file naming, and npm script
8
+ integration. Load when generating, regenerating, or configuring the
9
+ openapi-client-generator CLI.
10
+ type: core
11
+ library: openapi-client-generator
12
+ library_version: "3.0.0"
13
+ sources:
14
+ - "bazo/openapi-client-generator:src/bin.ts"
15
+ - "bazo/openapi-client-generator:src/pipeline.ts"
16
+ ---
17
+
18
+ # Generate Client
19
+
20
+ ## Setup
21
+
22
+ ```bash
23
+ npm install -D @bazo/openapi-client-generator
24
+ ```
25
+
26
+ Run the generator:
27
+
28
+ ```bash
29
+ npx openapi-client api.json out/ -n MyClient -m full
30
+ ```
31
+
32
+ Arguments and flags:
33
+
34
+ | Position/Flag | Required | Description |
35
+ | --- | --- | --- |
36
+ | `<spec.json>` | yes | Path to a local OpenAPI JSON file |
37
+ | `<output-dir>` | yes | Directory for the generated file |
38
+ | `-n, --name` | yes | Client class name (must be a valid TypeScript identifier) |
39
+ | `-m, --mode` | no | `full` (default), `playwright`, `swift`, or `kotlin` |
40
+
41
+ Save as an npm script:
42
+
43
+ ```json
44
+ {
45
+ "scripts": {
46
+ "generate-api": "openapi-client api.json src/generated/ -n ApiClient -m full"
47
+ }
48
+ }
49
+ ```
50
+
51
+ ## Core Patterns
52
+
53
+ ### Generate a full-mode TypeScript client (React Query + Wretch + Zod)
54
+
55
+ ```bash
56
+ npx openapi-client openapi.json src/api/ -n ApiClient -m full
57
+ ```
58
+
59
+ Produces `src/api/ApiClient.ts` with Zod schemas, React Query hooks, and a client class.
60
+
61
+ ### Generate a Playwright test client
62
+
63
+ ```bash
64
+ npx openapi-client openapi.json tests/api/ -n TestApi -m playwright
65
+ ```
66
+
67
+ Produces `tests/api/TestApi.ts` with async methods wrapping Playwright's `APIRequestContext`.
68
+
69
+ ### Generate a Swift client
70
+
71
+ ```bash
72
+ npx openapi-client openapi.json Sources/API/ -n ApiClient -m swift
73
+ ```
74
+
75
+ Produces `Sources/API/ApiClient.swift` with Codable structs and URLSession-based async methods.
76
+
77
+ ### Generate a Kotlin client
78
+
79
+ ```bash
80
+ npx openapi-client openapi.json src/main/kotlin/api/ -n ApiClient -m kotlin
81
+ ```
82
+
83
+ Produces `src/main/kotlin/api/ApiClient.kt` with `@Serializable` data classes and Ktor suspend functions.
84
+
85
+ ## Common Mistakes
86
+
87
+ ### CRITICAL Hallucinating non-existent CLI flags
88
+
89
+ Wrong:
90
+
91
+ ```bash
92
+ npx openapi-client api.json out/ -n MyClient --format json --validate --strict
93
+ ```
94
+
95
+ Correct:
96
+
97
+ ```bash
98
+ npx openapi-client api.json out/ -n MyClient -m full
99
+ ```
100
+
101
+ The CLI uses `parseArgs` with `strict: true`. Only `-n/--name`, `-m/--mode`, `-v/--version`, and `-h/--help` exist. Any other flag causes a hard error.
102
+
103
+ Source: src/bin.ts
104
+
105
+ ### HIGH Wrong positional argument order
106
+
107
+ Wrong:
108
+
109
+ ```bash
110
+ npx openapi-client out/ api.json -n MyClient
111
+ ```
112
+
113
+ Correct:
114
+
115
+ ```bash
116
+ npx openapi-client api.json out/ -n MyClient
117
+ ```
118
+
119
+ The first positional must be the spec file path, the second must be the output directory. Swapping them causes the tool to try reading a directory as a JSON file.
120
+
121
+ Source: src/bin.ts
122
+
123
+ ### HIGH Omitting the required --name flag
124
+
125
+ Wrong:
126
+
127
+ ```bash
128
+ npx openapi-client api.json out/ -m full
129
+ ```
130
+
131
+ Correct:
132
+
133
+ ```bash
134
+ npx openapi-client api.json out/ -n MyClient -m full
135
+ ```
136
+
137
+ The `-n/--name` flag is required. It sets the exported class name and output filename. The CLI exits with an error if missing.
138
+
139
+ Source: src/bin.ts
140
+
141
+ ### HIGH Passing a YAML spec or URL instead of a JSON file
142
+
143
+ Wrong:
144
+
145
+ ```bash
146
+ npx openapi-client https://api.example.com/openapi.yaml out/ -n MyClient
147
+ ```
148
+
149
+ Correct:
150
+
151
+ ```bash
152
+ npx openapi-client ./openapi.json out/ -n MyClient
153
+ ```
154
+
155
+ The parser expects a local JSON file path. YAML specs and remote URLs are not supported.
156
+
157
+ Source: src/parser/openapi-parser.ts
158
+
159
+ ### HIGH Using an invalid mode name
160
+
161
+ Wrong:
162
+
163
+ ```bash
164
+ npx openapi-client api.json out/ -n MyClient -m react-query
165
+ ```
166
+
167
+ Correct:
168
+
169
+ ```bash
170
+ npx openapi-client api.json out/ -n MyClient -m full
171
+ ```
172
+
173
+ Mode must be exactly `full`, `playwright`, `swift`, or `kotlin`. Aliases like `react-query`, `ts`, `ios`, or `android` are not recognized.
174
+
175
+ Source: src/bin.ts
176
+
177
+ See also: integrate-full-client/SKILL.md — peer deps and client instantiation for full mode
178
+ See also: integrate-playwright-client/SKILL.md — Playwright fixture setup for playwright mode
179
+ See also: integrate-swift-client/SKILL.md — Xcode integration for swift mode
180
+ See also: integrate-kotlin-client/SKILL.md — Ktor setup for kotlin mode
@@ -0,0 +1,178 @@
1
+ ---
2
+ name: integrate-full-client
3
+ description: >
4
+ Use the generated full-mode TypeScript client in a web application.
5
+ Covers peer dependencies (zod, wretch, @tanstack/react-query), client
6
+ class instantiation with baseUrl and QueryClient, React Query useQuery
7
+ and useMutation hooks, Wretch HTTP configuration via onHttpConfigure,
8
+ ApiResponse<T> type, query invalidation, and GenericWretchError. Load
9
+ when importing or using a generated full-mode client file.
10
+ type: framework
11
+ library: openapi-client-generator
12
+ library_version: "3.0.0"
13
+ requires:
14
+ - generate-client
15
+ sources:
16
+ - "bazo/openapi-client-generator:src/modes/full/index.ts"
17
+ - "bazo/openapi-client-generator:src/modes/full/query.ts"
18
+ - "bazo/openapi-client-generator:src/modes/full/mutation.ts"
19
+ ---
20
+
21
+ This skill builds on generate-client. Read it first for CLI usage.
22
+
23
+ # Integrate Full Client
24
+
25
+ ## Setup
26
+
27
+ Install peer dependencies required by the generated file:
28
+
29
+ ```bash
30
+ npm install zod wretch @tanstack/react-query
31
+ ```
32
+
33
+ Instantiate the client:
34
+
35
+ ```typescript
36
+ import { QueryClient } from "@tanstack/react-query";
37
+ import { MyClient } from "./generated/MyClient";
38
+
39
+ const queryClient = new QueryClient();
40
+ const api = new MyClient("https://api.example.com", queryClient);
41
+ ```
42
+
43
+ The constructor signature is:
44
+
45
+ ```typescript
46
+ constructor(
47
+ baseUrl: string,
48
+ queryClient: QueryClient,
49
+ options?: RequestInit,
50
+ onHttpConfigure?: (w: Http) => Http
51
+ )
52
+ ```
53
+
54
+ ## Core Patterns
55
+
56
+ ### Use a generated query hook in a React component
57
+
58
+ ```typescript
59
+ function TaskList() {
60
+ const { data, isLoading } = api.listTasks.useQuery({ page: 1, limit: 10 });
61
+
62
+ if (isLoading) return <div>Loading...</div>;
63
+ return <div>{data?.data.items.map(t => <div key={t.id}>{t.title}</div>)}</div>;
64
+ }
65
+ ```
66
+
67
+ Each query operation exposes `.useQuery(params, options?)` which returns a standard React Query result extended with `.key` (the query key) and `.invalidate()` (shortcut for `queryClient.invalidateQueries`).
68
+
69
+ ### Use a generated mutation hook
70
+
71
+ ```typescript
72
+ function CreateTask() {
73
+ const { mutate, isPending } = api.createTask.useMutation({
74
+ onSuccess: () => api.listTasks.useQuery.invalidate?.(),
75
+ });
76
+
77
+ return (
78
+ <button onClick={() => mutate({ body: { title: "New task", status: "todo" } })} disabled={isPending}>
79
+ Create
80
+ </button>
81
+ );
82
+ }
83
+ ```
84
+
85
+ Each mutation operation exposes `.useMutation(options?)`.
86
+
87
+ ### Use the query function directly (outside React)
88
+
89
+ ```typescript
90
+ const result = await api.listTasks.query({ page: 1, limit: 10 });
91
+ console.log(result.data); // typed response body
92
+ console.log(result.status); // HTTP status code
93
+ ```
94
+
95
+ Every operation also exposes a `.query()` or `.mutation()` function for non-React usage.
96
+
97
+ ### Configure HTTP with auth headers
98
+
99
+ ```typescript
100
+ const api = new MyClient(
101
+ "https://api.example.com",
102
+ queryClient,
103
+ undefined,
104
+ (http) => http.auth(`Bearer ${token}`)
105
+ );
106
+ ```
107
+
108
+ The `onHttpConfigure` callback receives a Wretch instance and must return one. Use it to add auth, interceptors, or middleware.
109
+
110
+ ## Common Mistakes
111
+
112
+ ### CRITICAL Missing peer dependencies
113
+
114
+ Wrong:
115
+
116
+ ```bash
117
+ npm install zod
118
+ # Generated file fails: Cannot find module 'wretch'
119
+ ```
120
+
121
+ Correct:
122
+
123
+ ```bash
124
+ npm install zod wretch @tanstack/react-query
125
+ ```
126
+
127
+ The generated full-mode file imports from `zod`, `wretch`, `wretch/addons/queryString`, and `@tanstack/react-query`. All four must be installed in the consuming project.
128
+
129
+ Source: src/modes/full/index.ts generateImports
130
+
131
+ ### CRITICAL Instantiating client without QueryClient
132
+
133
+ Wrong:
134
+
135
+ ```typescript
136
+ const api = new MyClient("https://api.example.com");
137
+ ```
138
+
139
+ Correct:
140
+
141
+ ```typescript
142
+ import { QueryClient } from "@tanstack/react-query";
143
+ const queryClient = new QueryClient();
144
+ const api = new MyClient("https://api.example.com", queryClient);
145
+ ```
146
+
147
+ The constructor requires both `baseUrl` and a `QueryClient` instance. The client uses a Proxy to lazily bind operations to the HTTP instance and QueryClient — without the QueryClient, hooks will fail at runtime.
148
+
149
+ Source: src/modes/full/index.ts generateClient
150
+
151
+ ### HIGH Editing the generated file directly
152
+
153
+ Wrong:
154
+
155
+ ```typescript
156
+ // Manually adding a custom method to MyClient.ts
157
+ export class MyClient {
158
+ // ...generated code...
159
+ async customMethod() { /* hand-written */ }
160
+ }
161
+ ```
162
+
163
+ Correct:
164
+
165
+ ```typescript
166
+ // Extend or wrap the generated client in a separate file
167
+ import { MyClient } from "./generated/MyClient";
168
+
169
+ class ExtendedClient extends MyClient {
170
+ async customMethod() { /* hand-written */ }
171
+ }
172
+ ```
173
+
174
+ The generated output is meant to be regenerated from the spec. Manual edits are overwritten on the next generation run.
175
+
176
+ Source: maintainer interview
177
+
178
+ See also: generate-client/SKILL.md — CLI usage for regenerating the client
@@ -0,0 +1,186 @@
1
+ ---
2
+ name: integrate-kotlin-client
3
+ description: >
4
+ Use the generated Kotlin client in an Android or JVM application. Covers
5
+ Ktor HttpClient and kotlinx.serialization dependencies, instantiation
6
+ with HttpClient and baseUrl string, suspend operation functions in
7
+ coroutine scope, @Serializable data classes, ApiResponse<T>, ApiException
8
+ handling, and content negotiation setup. Load when importing or using a
9
+ generated kotlin-mode client file.
10
+ type: framework
11
+ library: openapi-client-generator
12
+ library_version: "3.0.0"
13
+ requires:
14
+ - generate-client
15
+ sources:
16
+ - "bazo/openapi-client-generator:src/modes/kotlin/index.ts"
17
+ - "bazo/openapi-client-generator:src/modes/kotlin/query.ts"
18
+ - "bazo/openapi-client-generator:src/modes/kotlin/mutation.ts"
19
+ ---
20
+
21
+ This skill builds on generate-client. Read it first for CLI usage.
22
+
23
+ # Integrate Kotlin Client
24
+
25
+ ## Setup
26
+
27
+ Add dependencies to `build.gradle.kts`:
28
+
29
+ ```kotlin
30
+ plugins {
31
+ kotlin("plugin.serialization") version "2.1.0"
32
+ }
33
+
34
+ dependencies {
35
+ implementation("io.ktor:ktor-client-core:3.1.0")
36
+ implementation("io.ktor:ktor-client-cio:3.1.0")
37
+ implementation("io.ktor:ktor-client-content-negotiation:3.1.0")
38
+ implementation("io.ktor:ktor-serialization-kotlinx-json:3.1.0")
39
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
40
+ }
41
+ ```
42
+
43
+ Instantiate the client:
44
+
45
+ ```kotlin
46
+ import io.ktor.client.*
47
+ import io.ktor.client.plugins.contentnegotiation.*
48
+ import io.ktor.serialization.kotlinx.json.*
49
+
50
+ val httpClient = HttpClient(CIO) {
51
+ install(ContentNegotiation) {
52
+ json()
53
+ }
54
+ }
55
+
56
+ val api = ApiClient(client = httpClient, baseUrl = "https://api.example.com")
57
+ ```
58
+
59
+ The constructor signature is:
60
+
61
+ ```kotlin
62
+ class ApiClient(
63
+ private val client: HttpClient,
64
+ private val baseUrl: String
65
+ )
66
+ ```
67
+
68
+ ## Core Patterns
69
+
70
+ ### Call a query operation
71
+
72
+ ```kotlin
73
+ runBlocking {
74
+ val result = api.listTasks(page = 1, limit = 10)
75
+ println(result.data.items) // List<Task>
76
+ println(result.status) // 200
77
+ }
78
+ ```
79
+
80
+ All operations are `suspend` functions. Query parameters map to function parameters with defaults for optional ones.
81
+
82
+ ### Call a mutation operation
83
+
84
+ ```kotlin
85
+ runBlocking {
86
+ val result = api.createTask(
87
+ body = CreateTaskRequest(title = "Build feature", status = "todo")
88
+ )
89
+ println(result.data.id) // created task ID
90
+ }
91
+ ```
92
+
93
+ Mutations take a `body` parameter typed as the corresponding `@Serializable` data class.
94
+
95
+ ### Handle API errors
96
+
97
+ ```kotlin
98
+ runBlocking {
99
+ try {
100
+ val result = api.getTask(taskId = "nonexistent")
101
+ } catch (e: ApiException) {
102
+ println("HTTP ${e.statusCode}: ${e.body}")
103
+ println("URL: ${e.responseUrl}")
104
+ }
105
+ }
106
+ ```
107
+
108
+ Non-success responses throw `ApiException` with `statusCode`, `body`, `responseHeaders`, and `responseUrl`.
109
+
110
+ ## Common Mistakes
111
+
112
+ ### CRITICAL Missing Ktor or kotlinx.serialization dependencies
113
+
114
+ Wrong:
115
+
116
+ ```kotlin
117
+ // build.gradle.kts — missing ktor and serialization deps
118
+ dependencies {
119
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
120
+ }
121
+ ```
122
+
123
+ Correct:
124
+
125
+ ```kotlin
126
+ dependencies {
127
+ implementation("io.ktor:ktor-client-core:3.1.0")
128
+ implementation("io.ktor:ktor-client-cio:3.1.0")
129
+ implementation("io.ktor:ktor-client-content-negotiation:3.1.0")
130
+ implementation("io.ktor:ktor-serialization-kotlinx-json:3.1.0")
131
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
132
+ }
133
+ ```
134
+
135
+ The generated file imports `io.ktor.client.*` and `kotlinx.serialization.*`. Both Ktor client (with a chosen engine like CIO) and kotlinx-serialization-json must be in the project dependencies.
136
+
137
+ Source: src/modes/kotlin/index.ts generateImports
138
+
139
+ ### HIGH Calling suspend functions outside coroutine scope
140
+
141
+ Wrong:
142
+
143
+ ```kotlin
144
+ fun main() {
145
+ val result = api.getTask(taskId = "123") // Compilation error
146
+ }
147
+ ```
148
+
149
+ Correct:
150
+
151
+ ```kotlin
152
+ suspend fun main() {
153
+ val result = api.getTask(taskId = "123")
154
+ }
155
+ ```
156
+
157
+ All generated operations are `suspend` functions. They must be called from a coroutine scope, a `suspend` function, or a builder like `runBlocking`.
158
+
159
+ Source: src/modes/kotlin/query.ts
160
+
161
+ ### HIGH Editing the generated file directly
162
+
163
+ Wrong:
164
+
165
+ ```kotlin
166
+ // Adding a custom method directly in ApiClient.kt
167
+ class ApiClient(private val client: HttpClient, private val baseUrl: String) {
168
+ // ...generated code...
169
+ suspend fun customMethod() { /* hand-written */ }
170
+ }
171
+ ```
172
+
173
+ Correct:
174
+
175
+ ```kotlin
176
+ // Extend via extension functions in a separate file
177
+ suspend fun ApiClient.customMethod() {
178
+ /* hand-written */
179
+ }
180
+ ```
181
+
182
+ The generated output is meant to be regenerated from the spec. Manual edits are overwritten on the next generation run. Use Kotlin extension functions in a separate file for custom methods.
183
+
184
+ Source: maintainer interview
185
+
186
+ See also: generate-client/SKILL.md — CLI usage for regenerating the client