@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/README.md +167 -0
- package/bin.js +21603 -0
- package/package.json +22 -0
- package/skills/generate-client/SKILL.md +180 -0
- package/skills/integrate-full-client/SKILL.md +178 -0
- package/skills/integrate-kotlin-client/SKILL.md +186 -0
- package/skills/integrate-playwright-client/SKILL.md +165 -0
- package/skills/integrate-swift-client/SKILL.md +151 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: integrate-playwright-client
|
|
3
|
+
description: >
|
|
4
|
+
Use the generated playwright-mode client for E2E API testing in CI/CD.
|
|
5
|
+
Covers peer dependencies (zod, @playwright/test), instantiation from
|
|
6
|
+
Playwright APIRequestContext fixture, calling async operation methods,
|
|
7
|
+
ApiResponse<T> assertions, and Zod-validated response bodies. Load when
|
|
8
|
+
importing or using a generated playwright-mode client file in tests.
|
|
9
|
+
type: framework
|
|
10
|
+
library: openapi-client-generator
|
|
11
|
+
library_version: "3.0.0"
|
|
12
|
+
requires:
|
|
13
|
+
- generate-client
|
|
14
|
+
sources:
|
|
15
|
+
- "bazo/openapi-client-generator:src/modes/playwright/index.ts"
|
|
16
|
+
- "bazo/openapi-client-generator:src/modes/playwright/query.ts"
|
|
17
|
+
- "bazo/openapi-client-generator:src/modes/playwright/mutation.ts"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
This skill builds on generate-client. Read it first for CLI usage.
|
|
21
|
+
|
|
22
|
+
# Integrate Playwright Client
|
|
23
|
+
|
|
24
|
+
## Setup
|
|
25
|
+
|
|
26
|
+
Install peer dependencies:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -D zod @playwright/test
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Use the generated client in a Playwright test:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { test, expect } from "@playwright/test";
|
|
36
|
+
import { TestApi } from "./generated/TestApi";
|
|
37
|
+
|
|
38
|
+
test("list tasks returns 200", async ({ request }) => {
|
|
39
|
+
const api = new TestApi(request);
|
|
40
|
+
const result = await api.listTasks({ page: 1, limit: 10 });
|
|
41
|
+
expect(result.status).toBe(200);
|
|
42
|
+
expect(result.data.items.length).toBeGreaterThan(0);
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The constructor takes a single argument: Playwright's `APIRequestContext`, available from the `{ request }` test fixture.
|
|
47
|
+
|
|
48
|
+
## Core Patterns
|
|
49
|
+
|
|
50
|
+
### Query operation with parameters
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
test("get task by id", async ({ request }) => {
|
|
54
|
+
const api = new TestApi(request);
|
|
55
|
+
const result = await api.getTask({ taskId: "123" });
|
|
56
|
+
expect(result.status).toBe(200);
|
|
57
|
+
expect(result.data.id).toBe("123");
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
All operations are async methods on the client class. Path, query, and header parameters are passed as a single params object.
|
|
62
|
+
|
|
63
|
+
### Mutation operation with request body
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
test("create a task", async ({ request }) => {
|
|
67
|
+
const api = new TestApi(request);
|
|
68
|
+
const result = await api.createTask({
|
|
69
|
+
body: { title: "Test task", status: "todo" },
|
|
70
|
+
});
|
|
71
|
+
expect(result.status).toBe(201);
|
|
72
|
+
expect(result.data.title).toBe("Test task");
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Mutations accept a `body` property in the params object. The body is Zod-validated before sending.
|
|
77
|
+
|
|
78
|
+
### Assert on ApiResponse structure
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
test("check response shape", async ({ request }) => {
|
|
82
|
+
const api = new TestApi(request);
|
|
83
|
+
const result = await api.healthCheck();
|
|
84
|
+
expect(result).toEqual(
|
|
85
|
+
expect.objectContaining({
|
|
86
|
+
status: 200,
|
|
87
|
+
data: expect.any(Object),
|
|
88
|
+
headers: expect.any(Object),
|
|
89
|
+
url: expect.any(String),
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Every operation returns `ApiResponse<T>` with `data`, `status`, `headers`, and `url`.
|
|
96
|
+
|
|
97
|
+
## Common Mistakes
|
|
98
|
+
|
|
99
|
+
### CRITICAL Missing peer dependencies
|
|
100
|
+
|
|
101
|
+
Wrong:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm install -D @playwright/test
|
|
105
|
+
# Generated file fails: Cannot find module 'zod'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Correct:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
npm install -D zod @playwright/test
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The generated playwright-mode file imports both `zod` and `@playwright/test`. Both must be installed.
|
|
115
|
+
|
|
116
|
+
Source: src/modes/playwright/index.ts generateImports
|
|
117
|
+
|
|
118
|
+
### CRITICAL Passing a URL string instead of APIRequestContext
|
|
119
|
+
|
|
120
|
+
Wrong:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const api = new TestApi("https://api.example.com");
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Correct:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
test("api test", async ({ request }) => {
|
|
130
|
+
const api = new TestApi(request);
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The playwright client constructor takes an `APIRequestContext`, not a base URL. The request context comes from Playwright's `{ request }` test fixture, which handles base URL configuration via `playwright.config.ts`.
|
|
135
|
+
|
|
136
|
+
Source: src/modes/playwright/index.ts generateClient
|
|
137
|
+
|
|
138
|
+
### HIGH Editing the generated file directly
|
|
139
|
+
|
|
140
|
+
Wrong:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Adding a helper method directly in TestApi.ts
|
|
144
|
+
export class TestApi {
|
|
145
|
+
// ...generated methods...
|
|
146
|
+
async customHelper() { /* hand-written */ }
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Correct:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Create a wrapper in a separate file
|
|
154
|
+
import { TestApi } from "./generated/TestApi";
|
|
155
|
+
|
|
156
|
+
class ExtendedTestApi extends TestApi {
|
|
157
|
+
async customHelper() { /* hand-written */ }
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The generated output is meant to be regenerated from the spec. Manual edits are overwritten on the next generation run.
|
|
162
|
+
|
|
163
|
+
Source: maintainer interview
|
|
164
|
+
|
|
165
|
+
See also: generate-client/SKILL.md — CLI usage for regenerating the client
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: integrate-swift-client
|
|
3
|
+
description: >
|
|
4
|
+
Use the generated Swift client in an iOS or macOS application. Covers
|
|
5
|
+
adding the .swift file to Xcode, instantiation with URL and URLSession,
|
|
6
|
+
async/await operation calls, Codable struct schemas, ApiResponse<T>,
|
|
7
|
+
APIError enum handling, and Sendable conformance. Load when importing
|
|
8
|
+
or using a generated swift-mode client file.
|
|
9
|
+
type: framework
|
|
10
|
+
library: openapi-client-generator
|
|
11
|
+
library_version: "3.0.0"
|
|
12
|
+
requires:
|
|
13
|
+
- generate-client
|
|
14
|
+
sources:
|
|
15
|
+
- "bazo/openapi-client-generator:src/modes/swift/index.ts"
|
|
16
|
+
- "bazo/openapi-client-generator:src/modes/swift/query.ts"
|
|
17
|
+
- "bazo/openapi-client-generator:src/modes/swift/mutation.ts"
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
This skill builds on generate-client. Read it first for CLI usage.
|
|
21
|
+
|
|
22
|
+
# Integrate Swift Client
|
|
23
|
+
|
|
24
|
+
## Setup
|
|
25
|
+
|
|
26
|
+
No external dependencies required. The generated file uses only Foundation.
|
|
27
|
+
|
|
28
|
+
Add the generated `.swift` file to your Xcode project, then instantiate:
|
|
29
|
+
|
|
30
|
+
```swift
|
|
31
|
+
let api = ApiClient(baseURL: URL(string: "https://api.example.com")!)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The constructor signature is:
|
|
35
|
+
|
|
36
|
+
```swift
|
|
37
|
+
init(baseURL: URL, session: URLSession = .shared)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Core Patterns
|
|
41
|
+
|
|
42
|
+
### Call a query operation
|
|
43
|
+
|
|
44
|
+
```swift
|
|
45
|
+
let result = try await api.listTasks(page: 1, limit: 10)
|
|
46
|
+
print(result.data.items) // [Task]
|
|
47
|
+
print(result.status) // 200
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
All operations are `async throws` functions. Query parameters map to function parameters with defaults for optional ones.
|
|
51
|
+
|
|
52
|
+
### Call a mutation operation
|
|
53
|
+
|
|
54
|
+
```swift
|
|
55
|
+
let newTask = CreateTaskRequest(title: "Build feature", status: "todo", description: nil)
|
|
56
|
+
let result = try await api.createTask(body: newTask)
|
|
57
|
+
print(result.data.id) // created task ID
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Mutations take a `body` parameter typed as the corresponding Codable request struct.
|
|
61
|
+
|
|
62
|
+
### Handle API errors
|
|
63
|
+
|
|
64
|
+
```swift
|
|
65
|
+
do {
|
|
66
|
+
let result = try await api.getTask(taskId: "nonexistent")
|
|
67
|
+
} catch let error as APIError {
|
|
68
|
+
switch error {
|
|
69
|
+
case .badResponse(let statusCode, let data):
|
|
70
|
+
print("HTTP \(statusCode)")
|
|
71
|
+
case .decodingError(let error):
|
|
72
|
+
print("Decode failed: \(error)")
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Non-success responses throw `APIError.badResponse`. Decoding failures throw `APIError.decodingError`.
|
|
78
|
+
|
|
79
|
+
### Use a custom URLSession
|
|
80
|
+
|
|
81
|
+
```swift
|
|
82
|
+
let config = URLSessionConfiguration.default
|
|
83
|
+
config.httpAdditionalHeaders = ["Authorization": "Bearer \(token)"]
|
|
84
|
+
let session = URLSession(configuration: config)
|
|
85
|
+
let api = ApiClient(baseURL: URL(string: "https://api.example.com")!, session: session)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Common Mistakes
|
|
89
|
+
|
|
90
|
+
### HIGH Providing String instead of URL for baseURL
|
|
91
|
+
|
|
92
|
+
Wrong:
|
|
93
|
+
|
|
94
|
+
```swift
|
|
95
|
+
let api = ApiClient(baseURL: "https://api.example.com")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Correct:
|
|
99
|
+
|
|
100
|
+
```swift
|
|
101
|
+
let api = ApiClient(baseURL: URL(string: "https://api.example.com")!)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The constructor parameter is typed as `URL`, not `String`. Use `URL(string:)` which returns an optional — force-unwrap only for known-good URLs.
|
|
105
|
+
|
|
106
|
+
Source: src/modes/swift/index.ts generateClient
|
|
107
|
+
|
|
108
|
+
### HIGH Not using async/await for operations
|
|
109
|
+
|
|
110
|
+
Wrong:
|
|
111
|
+
|
|
112
|
+
```swift
|
|
113
|
+
let result = api.getTask(taskId: "123")
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Correct:
|
|
117
|
+
|
|
118
|
+
```swift
|
|
119
|
+
let result = try await api.getTask(taskId: "123")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
All generated operations are `async throws` functions. They must be called with `try await` from an async context.
|
|
123
|
+
|
|
124
|
+
Source: src/modes/swift/query.ts
|
|
125
|
+
|
|
126
|
+
### HIGH Editing the generated file directly
|
|
127
|
+
|
|
128
|
+
Wrong:
|
|
129
|
+
|
|
130
|
+
```swift
|
|
131
|
+
// Adding a custom method directly in ApiClient.swift
|
|
132
|
+
class ApiClient: @unchecked Sendable {
|
|
133
|
+
// ...generated code...
|
|
134
|
+
func customMethod() async throws { /* hand-written */ }
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Correct:
|
|
139
|
+
|
|
140
|
+
```swift
|
|
141
|
+
// Extend in a separate file
|
|
142
|
+
extension ApiClient {
|
|
143
|
+
func customMethod() async throws { /* hand-written */ }
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The generated output is meant to be regenerated from the spec. Manual edits are overwritten on the next generation run. Use Swift extensions in a separate file for custom methods.
|
|
148
|
+
|
|
149
|
+
Source: maintainer interview
|
|
150
|
+
|
|
151
|
+
See also: generate-client/SKILL.md — CLI usage for regenerating the client
|