zod-codegen 1.2.0 → 1.2.1
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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## <small>1.2.1 (2025-11-19)</small>
|
|
2
|
+
|
|
3
|
+
- Merge pull request #33 from julienandreu/fix/add-z-infer-to-response-types ([a14d81c](https://github.com/julienandreu/zod-codegen/commit/a14d81c)), closes [#33](https://github.com/julienandreu/zod-codegen/issues/33)
|
|
4
|
+
- fix: add z.infer to response types in generated methods ([c45ac77](https://github.com/julienandreu/zod-codegen/commit/c45ac77))
|
|
5
|
+
|
|
1
6
|
## 1.2.0 (2025-11-19)
|
|
2
7
|
|
|
3
8
|
- Merge pull request #31 from julienandreu/dependabot/npm_and_yarn/dev-dependencies-1dd8918b9f ([97ebb65](https://github.com/julienandreu/zod-codegen/commit/97ebb65)), closes [#31](https://github.com/julienandreu/zod-codegen/issues/31)
|
|
@@ -516,9 +516,36 @@ export class TypeScriptCodeGeneratorService {
|
|
|
516
516
|
}
|
|
517
517
|
const responseSchema = response.content['application/json'].schema;
|
|
518
518
|
const typeName = this.getSchemaTypeName(responseSchema, schemas);
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
519
|
+
const inferredType = this.wrapTypeWithZInfer(typeName, schemas);
|
|
520
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [inferredType]);
|
|
521
|
+
}
|
|
522
|
+
wrapTypeWithZInfer(typeName, schemas) {
|
|
523
|
+
// Primitive types and Record types don't need z.infer
|
|
524
|
+
const primitiveTypes = ['string', 'number', 'boolean', 'unknown'];
|
|
525
|
+
if (primitiveTypes.includes(typeName) || typeName.startsWith('Record<')) {
|
|
526
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
527
|
+
}
|
|
528
|
+
// Handle array types like "Pet[]"
|
|
529
|
+
if (typeName.endsWith('[]')) {
|
|
530
|
+
const itemTypeName = typeName.slice(0, -2);
|
|
531
|
+
const sanitizedItemTypeName = this.typeBuilder.sanitizeIdentifier(itemTypeName);
|
|
532
|
+
// Check if the item type is a custom schema
|
|
533
|
+
if (schemas[sanitizedItemTypeName]) {
|
|
534
|
+
// Return z.infer<typeof ItemType>[]
|
|
535
|
+
const zInferType = ts.factory.createTypeReferenceNode(ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('infer')), [ts.factory.createTypeQueryNode(ts.factory.createIdentifier(sanitizedItemTypeName), undefined)]);
|
|
536
|
+
return ts.factory.createArrayTypeNode(zInferType);
|
|
537
|
+
}
|
|
538
|
+
// If it's a primitive array, return as-is
|
|
539
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
540
|
+
}
|
|
541
|
+
// Handle custom schema types
|
|
542
|
+
const sanitizedTypeName = this.typeBuilder.sanitizeIdentifier(typeName);
|
|
543
|
+
if (schemas[sanitizedTypeName]) {
|
|
544
|
+
// Return z.infer<typeof TypeName>
|
|
545
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('infer')), [ts.factory.createTypeQueryNode(ts.factory.createIdentifier(sanitizedTypeName), undefined)]);
|
|
546
|
+
}
|
|
547
|
+
// Fallback: return as-is if we can't determine
|
|
548
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
522
549
|
}
|
|
523
550
|
buildServerConfiguration(openapi) {
|
|
524
551
|
const servers = openapi.servers;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
2
|
-
// Built with zod-codegen@1.
|
|
3
|
-
// Latest edit:
|
|
2
|
+
// Built with zod-codegen@1.1.2
|
|
3
|
+
// Latest edit: Wed, 19 Nov 2025 16:26:25 GMT
|
|
4
4
|
// Source file: ./samples/swagger-petstore.yaml
|
|
5
5
|
/* eslint-disable */
|
|
6
6
|
// @ts-nocheck
|
|
@@ -144,73 +144,209 @@ export class SwaggerPetstoreOpenAPI30 {
|
|
|
144
144
|
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
145
145
|
return await response.json();
|
|
146
146
|
}
|
|
147
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Add a new pet to the store
|
|
149
|
+
* @param body Create a new pet in the store
|
|
150
|
+
* @returns {z.infer<typeof Pet>}
|
|
151
|
+
*/
|
|
152
|
+
async addPet(body: Pet): Promise<z.infer<typeof Pet>> {
|
|
148
153
|
return Pet.parse(
|
|
149
154
|
await this.#makeRequest('POST', '/pet', {data: body, contentType: 'application/x-www-form-urlencoded'}),
|
|
150
155
|
);
|
|
151
156
|
}
|
|
152
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Update an existing pet
|
|
159
|
+
*
|
|
160
|
+
* Update an existing pet by Id
|
|
161
|
+
* @param body Update an existent pet in the store
|
|
162
|
+
* @returns {z.infer<typeof Pet>}
|
|
163
|
+
*/
|
|
164
|
+
async updatePet(body: Pet): Promise<z.infer<typeof Pet>> {
|
|
153
165
|
return Pet.parse(
|
|
154
166
|
await this.#makeRequest('PUT', '/pet', {data: body, contentType: 'application/x-www-form-urlencoded'}),
|
|
155
167
|
);
|
|
156
168
|
}
|
|
157
|
-
|
|
169
|
+
/**
|
|
170
|
+
* Finds Pets by status
|
|
171
|
+
*
|
|
172
|
+
* Multiple status values can be provided with comma separated strings
|
|
173
|
+
*
|
|
174
|
+
* @param status Status values that need to be considered for filter
|
|
175
|
+
* @returns {z.infer<typeof Pet>[]}
|
|
176
|
+
*/
|
|
177
|
+
async findPetsByStatus(status?: string): Promise<z.infer<typeof Pet>[]> {
|
|
158
178
|
return await this.#makeRequest('GET', '/pet/findByStatus', {params: {status: status}});
|
|
159
179
|
}
|
|
160
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Finds Pets by tags
|
|
182
|
+
*
|
|
183
|
+
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
|
184
|
+
*
|
|
185
|
+
* @param tags Tags to filter by
|
|
186
|
+
* @returns {z.infer<typeof Pet>[]}
|
|
187
|
+
*/
|
|
188
|
+
async findPetsByTags(tags?: string[]): Promise<z.infer<typeof Pet>[]> {
|
|
161
189
|
return await this.#makeRequest('GET', '/pet/findByTags', {params: {tags: tags}});
|
|
162
190
|
}
|
|
163
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Find pet by ID
|
|
193
|
+
*
|
|
194
|
+
* Returns a single pet
|
|
195
|
+
*
|
|
196
|
+
* @param petId ID of pet to return
|
|
197
|
+
* @returns {z.infer<typeof Pet>}
|
|
198
|
+
*/
|
|
199
|
+
async getPetById(petId: number): Promise<z.infer<typeof Pet>> {
|
|
164
200
|
return Pet.parse(await this.#makeRequest('GET', `/pet/${petId}`, {}));
|
|
165
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Updates a pet in the store with form data
|
|
204
|
+
*
|
|
205
|
+
* @param petId ID of pet that needs to be updated
|
|
206
|
+
* @param name Name of pet that needs to be updated
|
|
207
|
+
* @param status Status of pet that needs to be updated
|
|
208
|
+
* @returns {void}
|
|
209
|
+
*/
|
|
166
210
|
async updatePetWithForm(petId: number, name?: string, status?: string): Promise<void> {
|
|
167
211
|
return await this.#makeRequest('POST', `/pet/${petId}`, {params: {name: name, status: status}});
|
|
168
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Deletes a pet
|
|
215
|
+
*
|
|
216
|
+
* delete a pet
|
|
217
|
+
*
|
|
218
|
+
* @param api_key
|
|
219
|
+
* @param petId Pet id to delete
|
|
220
|
+
* @returns {void}
|
|
221
|
+
*/
|
|
169
222
|
async deletePet(petId: number): Promise<void> {
|
|
170
223
|
return await this.#makeRequest('DELETE', `/pet/${petId}`, {});
|
|
171
224
|
}
|
|
172
|
-
|
|
225
|
+
/**
|
|
226
|
+
* uploads an image
|
|
227
|
+
*
|
|
228
|
+
* @param petId ID of pet to update
|
|
229
|
+
* @param additionalMetadata Additional Metadata
|
|
230
|
+
* @param body
|
|
231
|
+
* @returns {z.infer<typeof ApiResponse>}
|
|
232
|
+
*/
|
|
233
|
+
async uploadFile(petId: number, additionalMetadata?: string): Promise<z.infer<typeof ApiResponse>> {
|
|
173
234
|
return ApiResponse.parse(
|
|
174
235
|
await this.#makeRequest('POST', `/pet/${petId}/uploadImage`, {params: {additionalMetadata: additionalMetadata}}),
|
|
175
236
|
);
|
|
176
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Returns pet inventories by status
|
|
240
|
+
*
|
|
241
|
+
* Returns a map of status codes to quantities
|
|
242
|
+
* @returns {Record<string, unknown>}
|
|
243
|
+
*/
|
|
177
244
|
async getInventory(): Promise<Record<string, unknown>> {
|
|
178
245
|
return await this.#makeRequest('GET', '/store/inventory', {});
|
|
179
246
|
}
|
|
180
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Place an order for a pet
|
|
249
|
+
*
|
|
250
|
+
* Place a new order in the store
|
|
251
|
+
* @param body
|
|
252
|
+
* @returns {z.infer<typeof Order>}
|
|
253
|
+
*/
|
|
254
|
+
async placeOrder(body?: Order): Promise<z.infer<typeof Order>> {
|
|
181
255
|
return Order.parse(
|
|
182
256
|
await this.#makeRequest('POST', '/store/order', {data: body, contentType: 'application/x-www-form-urlencoded'}),
|
|
183
257
|
);
|
|
184
258
|
}
|
|
185
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Find purchase order by ID
|
|
261
|
+
*
|
|
262
|
+
* For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions.
|
|
263
|
+
*
|
|
264
|
+
* @param orderId ID of order that needs to be fetched
|
|
265
|
+
* @returns {z.infer<typeof Order>}
|
|
266
|
+
*/
|
|
267
|
+
async getOrderById(orderId: number): Promise<z.infer<typeof Order>> {
|
|
186
268
|
return Order.parse(await this.#makeRequest('GET', `/store/order/${orderId}`, {}));
|
|
187
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* Delete purchase order by ID
|
|
272
|
+
*
|
|
273
|
+
* For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
|
|
274
|
+
*
|
|
275
|
+
* @param orderId ID of the order that needs to be deleted
|
|
276
|
+
* @returns {void}
|
|
277
|
+
*/
|
|
188
278
|
async deleteOrder(orderId: number): Promise<void> {
|
|
189
279
|
return await this.#makeRequest('DELETE', `/store/order/${orderId}`, {});
|
|
190
280
|
}
|
|
191
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Create user
|
|
283
|
+
*
|
|
284
|
+
* This can only be done by the logged in user.
|
|
285
|
+
* @param body Created user object
|
|
286
|
+
* @returns {z.infer<typeof User>}
|
|
287
|
+
*/
|
|
288
|
+
async createUser(body?: User): Promise<z.infer<typeof User>> {
|
|
192
289
|
return User.parse(
|
|
193
290
|
await this.#makeRequest('POST', '/user', {data: body, contentType: 'application/x-www-form-urlencoded'}),
|
|
194
291
|
);
|
|
195
292
|
}
|
|
196
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Creates list of users with given input array
|
|
295
|
+
* @param body
|
|
296
|
+
* @returns {z.infer<typeof User>}
|
|
297
|
+
*/
|
|
298
|
+
async createUsersWithListInput(body?: User[]): Promise<z.infer<typeof User>> {
|
|
197
299
|
return User.parse(await this.#makeRequest('POST', '/user/createWithList', {data: body}));
|
|
198
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Logs user into the system
|
|
303
|
+
*
|
|
304
|
+
* @param username The user name for login
|
|
305
|
+
* @param password The password for login in clear text
|
|
306
|
+
* @returns {string}
|
|
307
|
+
*/
|
|
199
308
|
async loginUser(username?: string, password?: string): Promise<string> {
|
|
200
309
|
return await this.#makeRequest('GET', '/user/login', {params: {username: username, password: password}});
|
|
201
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Logs out current logged in user session
|
|
313
|
+
* @returns {void}
|
|
314
|
+
*/
|
|
202
315
|
async logoutUser(): Promise<void> {
|
|
203
316
|
return await this.#makeRequest('GET', '/user/logout', {});
|
|
204
317
|
}
|
|
205
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Get user by user name
|
|
320
|
+
*
|
|
321
|
+
* @param username The name that needs to be fetched. Use user1 for testing.
|
|
322
|
+
* @returns {z.infer<typeof User>}
|
|
323
|
+
*/
|
|
324
|
+
async getUserByName(username: string): Promise<z.infer<typeof User>> {
|
|
206
325
|
return User.parse(await this.#makeRequest('GET', `/user/${username}`, {}));
|
|
207
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Update user
|
|
329
|
+
*
|
|
330
|
+
* This can only be done by the logged in user.
|
|
331
|
+
*
|
|
332
|
+
* @param username name that need to be deleted
|
|
333
|
+
* @param body Update an existent user in the store
|
|
334
|
+
* @returns {void}
|
|
335
|
+
*/
|
|
208
336
|
async updateUser(username: string, body?: User): Promise<void> {
|
|
209
337
|
return await this.#makeRequest('PUT', `/user/${username}`, {
|
|
210
338
|
data: body,
|
|
211
339
|
contentType: 'application/x-www-form-urlencoded',
|
|
212
340
|
});
|
|
213
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Delete user
|
|
344
|
+
*
|
|
345
|
+
* This can only be done by the logged in user.
|
|
346
|
+
*
|
|
347
|
+
* @param username The name that needs to be deleted
|
|
348
|
+
* @returns {void}
|
|
349
|
+
*/
|
|
214
350
|
async deleteUser(username: string): Promise<void> {
|
|
215
351
|
return await this.#makeRequest('DELETE', `/user/${username}`, {});
|
|
216
352
|
}
|
package/package.json
CHANGED
|
@@ -1264,10 +1264,48 @@ export class TypeScriptCodeGeneratorService implements CodeGenerator, SchemaBuil
|
|
|
1264
1264
|
|
|
1265
1265
|
const responseSchema = response.content['application/json'].schema;
|
|
1266
1266
|
const typeName = this.getSchemaTypeName(responseSchema, schemas);
|
|
1267
|
+
const inferredType = this.wrapTypeWithZInfer(typeName, schemas);
|
|
1267
1268
|
|
|
1268
|
-
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
|
|
1269
|
-
|
|
1270
|
-
|
|
1269
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [inferredType]);
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
private wrapTypeWithZInfer(typeName: string, schemas: Record<string, ts.VariableStatement>): ts.TypeNode {
|
|
1273
|
+
// Primitive types and Record types don't need z.infer
|
|
1274
|
+
const primitiveTypes = ['string', 'number', 'boolean', 'unknown'];
|
|
1275
|
+
if (primitiveTypes.includes(typeName) || typeName.startsWith('Record<')) {
|
|
1276
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
// Handle array types like "Pet[]"
|
|
1280
|
+
if (typeName.endsWith('[]')) {
|
|
1281
|
+
const itemTypeName = typeName.slice(0, -2);
|
|
1282
|
+
const sanitizedItemTypeName = this.typeBuilder.sanitizeIdentifier(itemTypeName);
|
|
1283
|
+
|
|
1284
|
+
// Check if the item type is a custom schema
|
|
1285
|
+
if (schemas[sanitizedItemTypeName]) {
|
|
1286
|
+
// Return z.infer<typeof ItemType>[]
|
|
1287
|
+
const zInferType = ts.factory.createTypeReferenceNode(
|
|
1288
|
+
ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('infer')),
|
|
1289
|
+
[ts.factory.createTypeQueryNode(ts.factory.createIdentifier(sanitizedItemTypeName), undefined)],
|
|
1290
|
+
);
|
|
1291
|
+
return ts.factory.createArrayTypeNode(zInferType);
|
|
1292
|
+
}
|
|
1293
|
+
// If it's a primitive array, return as-is
|
|
1294
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
// Handle custom schema types
|
|
1298
|
+
const sanitizedTypeName = this.typeBuilder.sanitizeIdentifier(typeName);
|
|
1299
|
+
if (schemas[sanitizedTypeName]) {
|
|
1300
|
+
// Return z.infer<typeof TypeName>
|
|
1301
|
+
return ts.factory.createTypeReferenceNode(
|
|
1302
|
+
ts.factory.createQualifiedName(ts.factory.createIdentifier('z'), ts.factory.createIdentifier('infer')),
|
|
1303
|
+
[ts.factory.createTypeQueryNode(ts.factory.createIdentifier(sanitizedTypeName), undefined)],
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
// Fallback: return as-is if we can't determine
|
|
1308
|
+
return ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(typeName), undefined);
|
|
1271
1309
|
}
|
|
1272
1310
|
|
|
1273
1311
|
private buildServerConfiguration(openapi: OpenApiSpecType): ts.Statement[] {
|