fork of hey-api/openapi-ts because I need some additional things

fix(client-ky): resolve TypeScript type errors

Fix TypeScript compilation errors without using `as any`:

- Use inline array type instead of accessing `KyOptions['retry']['methods']`
to avoid type error when retry can be number | object
- Add type assertion for headers as HeadersInit to satisfy Request constructor
- Change body type from `BodyInit | null` to `unknown` for consistency with
client-fetch and to allow testing with edge case values
- Use `Partial<KyInstance> as KyInstance` pattern in tests (same as client-axios)
to properly type mock ky instances without `as any`

+53 -45
+37 -40
packages/openapi-ts/src/plugins/@hey-api/client-ky/__tests__/client.test.ts
··· 1 + import type { KyInstance } from 'ky'; 1 2 import { HTTPError } from 'ky'; 2 3 import { describe, expect, it, vi } from 'vitest'; 3 4 4 5 import type { ResolvedRequestOptions } from '../bundle'; 5 6 import { createClient } from '../bundle/client'; 6 - 7 - type MockKy = ((...args: any[]) => any) & { 8 - preconnect?: any; 9 - }; 10 7 11 8 describe('buildUrl', () => { 12 9 const client = createClient(); ··· 87 84 status: 200, 88 85 }); 89 86 90 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 87 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 91 88 92 89 const result = await client.request({ 93 - ky: mockKy, 90 + ky: mockKy as Partial<KyInstance> as KyInstance, 94 91 method: 'GET', 95 92 url: '/test', 96 93 }); ··· 107 104 status: 200, 108 105 }); 109 106 110 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 107 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 111 108 112 109 const result = await client.request({ 113 - ky: mockKy, 110 + ky: mockKy as Partial<KyInstance> as KyInstance, 114 111 method: 'GET', 115 112 parseAs: 'arrayBuffer', 116 113 url: '/test', ··· 129 126 status: 200, 130 127 }); 131 128 132 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 129 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 133 130 134 131 const result = await client.request({ 135 - ky: mockKy, 132 + ky: mockKy as Partial<KyInstance> as KyInstance, 136 133 method: 'GET', 137 134 url: '/test', 138 135 }); ··· 149 146 status: 200, 150 147 }); 151 148 152 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 149 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 153 150 154 151 const result = await client.request({ 155 - ky: mockKy, 152 + ky: mockKy as Partial<KyInstance> as KyInstance, 156 153 method: 'GET', 157 154 url: '/test', 158 155 }); ··· 169 166 status: 200, 170 167 }); 171 168 172 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 169 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 173 170 174 171 const result = await client.request({ 175 - ky: mockKy, 172 + ky: mockKy as Partial<KyInstance> as KyInstance, 176 173 method: 'GET', 177 174 url: '/test', 178 175 }); ··· 190 187 status: 200, 191 188 }); 192 189 193 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 190 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 194 191 195 192 const result = await client.request({ 196 - ky: mockKy, 193 + ky: mockKy as Partial<KyInstance> as KyInstance, 197 194 method: 'GET', 198 195 parseAs: 'stream', 199 196 url: '/test', ··· 211 208 status: 200, 212 209 }); 213 210 214 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 211 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 215 212 216 213 const result = await client.request({ 217 - ky: mockKy, 214 + ky: mockKy as Partial<KyInstance> as KyInstance, 218 215 method: 'GET', 219 216 url: '/test', 220 217 }); ··· 244 241 status: 200, 245 242 }); 246 243 247 - const mockKy: MockKy = vi.fn().mockResolvedValueOnce(mockResponse); 244 + const mockKy = vi.fn().mockResolvedValueOnce(mockResponse); 248 245 249 246 const result = await client.post({ 250 247 body, ··· 252 249 headers: { 253 250 'Content-Type': 'text/plain', 254 251 }, 255 - ky: mockKy, 252 + ky: mockKy as Partial<KyInstance> as KyInstance, 256 253 url: '/test', 257 254 }); 258 255 ··· 319 316 status: 200, 320 317 }); 321 318 322 - const mockKy: MockKy = vi.fn().mockResolvedValueOnce(mockResponse); 319 + const mockKy = vi.fn().mockResolvedValueOnce(mockResponse); 323 320 324 321 const result = await client.post({ 325 322 body, ··· 327 324 headers: { 328 325 'Content-Type': 'application/json', 329 326 }, 330 - ky: mockKy, 327 + ky: mockKy as Partial<KyInstance> as KyInstance, 331 328 url: '/test', 332 329 }); 333 330 ··· 376 373 status: 200, 377 374 }); 378 375 379 - const mockKy: MockKy = vi.fn().mockResolvedValueOnce(mockResponse); 376 + const mockKy = vi.fn().mockResolvedValueOnce(mockResponse); 380 377 381 378 const mockRequestInterceptor = vi 382 379 .fn() ··· 399 396 headers: { 400 397 'Content-Type': contentType, 401 398 }, 402 - ky: mockKy, 399 + ky: mockKy as Partial<KyInstance> as KyInstance, 403 400 url: '/test', 404 401 }); 405 402 ··· 421 418 status: 200, 422 419 }); 423 420 424 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 421 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 425 422 426 423 const mockResponseInterceptor = vi 427 424 .fn() ··· 435 432 ); 436 433 437 434 await client.get({ 438 - ky: mockKy, 435 + ky: mockKy as Partial<KyInstance> as KyInstance, 439 436 url: '/test', 440 437 }); 441 438 ··· 459 456 }, 460 457 ); 461 458 462 - const mockKy: MockKy = vi.fn().mockRejectedValue( 459 + const mockKy = vi.fn().mockRejectedValue( 463 460 new HTTPError(errorResponse, new Request('https://example.com/test'), { 464 461 method: 'GET', 465 462 } as any), 466 463 ); 467 464 468 465 const result = await client.get({ 469 - ky: mockKy, 466 + ky: mockKy as Partial<KyInstance> as KyInstance, 470 467 throwOnError: false, 471 468 url: '/test', 472 469 }); ··· 486 483 }, 487 484 ); 488 485 489 - const mockKy: MockKy = vi.fn().mockRejectedValue( 486 + const mockKy = vi.fn().mockRejectedValue( 490 487 new HTTPError(errorResponse, new Request('https://example.com/test'), { 491 488 method: 'GET', 492 489 } as any), ··· 494 491 495 492 await expect( 496 493 client.get({ 497 - ky: mockKy, 494 + ky: mockKy as Partial<KyInstance> as KyInstance, 498 495 throwOnError: true, 499 496 url: '/test', 500 497 }), ··· 506 503 status: 500, 507 504 }); 508 505 509 - const mockKy: MockKy = vi.fn().mockRejectedValue( 506 + const mockKy = vi.fn().mockRejectedValue( 510 507 new HTTPError(errorResponse, new Request('https://example.com/test'), { 511 508 method: 'GET', 512 509 } as any), 513 510 ); 514 511 515 512 const result = await client.get({ 516 - ky: mockKy, 513 + ky: mockKy as Partial<KyInstance> as KyInstance, 517 514 throwOnError: false, 518 515 url: '/test', 519 516 }); ··· 537 534 }, 538 535 ); 539 536 540 - const mockKy: MockKy = vi.fn().mockRejectedValue( 537 + const mockKy = vi.fn().mockRejectedValue( 541 538 new HTTPError(errorResponse, new Request('https://example.com/test'), { 542 539 method: 'GET', 543 540 } as any), ··· 550 547 const interceptorId = client.interceptors.error.use(mockErrorInterceptor); 551 548 552 549 const result = await client.get({ 553 - ky: mockKy, 550 + ky: mockKy as Partial<KyInstance> as KyInstance, 554 551 throwOnError: false, 555 552 url: '/test', 556 553 }); ··· 573 570 status: 200, 574 571 }); 575 572 576 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 573 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 577 574 578 575 await client.get({ 579 - ky: mockKy, 576 + ky: mockKy as Partial<KyInstance> as KyInstance, 580 577 retry: { 581 578 limit: 3, 582 579 methods: ['get', 'post'], ··· 612 609 status: 200, 613 610 }); 614 611 615 - const mockKy: MockKy = vi.fn().mockResolvedValue(mockResponse); 612 + const mockKy = vi.fn().mockResolvedValue(mockResponse); 616 613 617 614 const result = await client.get({ 618 - ky: mockKy, 615 + ky: mockKy as Partial<KyInstance> as KyInstance, 619 616 url: '/test', 620 617 }); 621 618 ··· 635 632 }, 636 633 ); 637 634 638 - const mockKy: MockKy = vi.fn().mockRejectedValue( 635 + const mockKy = vi.fn().mockRejectedValue( 639 636 new HTTPError(errorResponse, new Request('https://example.com/test'), { 640 637 method: 'GET', 641 638 } as any), 642 639 ); 643 640 644 641 const result = await client.get({ 645 - ky: mockKy, 642 + ky: mockKy as Partial<KyInstance> as KyInstance, 646 643 throwOnError: false, 647 644 url: '/test', 648 645 });
+15 -4
packages/openapi-ts/src/plugins/@hey-api/client-ky/bundle/client.ts
··· 9 9 Config, 10 10 RequestOptions, 11 11 ResolvedRequestOptions, 12 + RetryOptions, 12 13 } from './types'; 13 14 import type { Middleware } from './utils'; 14 15 import { ··· 146 147 }; 147 148 148 149 if (opts.retry && typeof opts.retry === 'object') { 150 + const retryOpts = opts.retry as RetryOptions; 149 151 kyOptions.retry = { 150 - limit: opts.retry.limit ?? 2, 151 - methods: opts.retry.methods as KyOptions['retry']['methods'], 152 - statusCodes: opts.retry.statusCodes, 152 + limit: retryOpts.limit ?? 2, 153 + methods: retryOpts.methods as Array< 154 + | 'get' 155 + | 'post' 156 + | 'put' 157 + | 'patch' 158 + | 'head' 159 + | 'delete' 160 + | 'options' 161 + | 'trace' 162 + >, 163 + statusCodes: retryOpts.statusCodes, 153 164 }; 154 165 } 155 166 156 167 let request = new Request(url, { 157 168 body: kyOptions.body as BodyInit, 158 - headers: kyOptions.headers, 169 + headers: kyOptions.headers as HeadersInit, 159 170 method: kyOptions.method, 160 171 }); 161 172
+1 -1
packages/openapi-ts/src/plugins/@hey-api/client-ky/bundle/types.ts
··· 116 116 * 117 117 * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} 118 118 */ 119 - body?: BodyInit | null; 119 + body?: unknown; 120 120 path?: Record<string, unknown>; 121 121 query?: Record<string, unknown>; 122 122 /**