@geekmidas/client 9.0.2 → 10.0.0-alpha.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.
Files changed (79) hide show
  1. package/dist/auth-fetcher-CBYuL6rx.d.cts +158 -0
  2. package/dist/auth-fetcher-CBYuL6rx.d.cts.map +1 -0
  3. package/dist/auth-fetcher-DOj0iz21.mjs +77 -0
  4. package/dist/auth-fetcher-DOj0iz21.mjs.map +1 -0
  5. package/dist/auth-fetcher-DxS8zOLc.d.mts +158 -0
  6. package/dist/auth-fetcher-DxS8zOLc.d.mts.map +1 -0
  7. package/dist/auth-fetcher-HILABmws.cjs +82 -0
  8. package/dist/auth-fetcher-HILABmws.cjs.map +1 -0
  9. package/dist/auth-fetcher.cjs +3 -76
  10. package/dist/auth-fetcher.d.cts +3 -158
  11. package/dist/auth-fetcher.d.mts +3 -158
  12. package/dist/auth-fetcher.mjs +3 -76
  13. package/dist/endpoint-hooks.d.mts +1 -1
  14. package/dist/fetcher-C1xtCKpT.d.mts +25 -0
  15. package/dist/fetcher-C1xtCKpT.d.mts.map +1 -0
  16. package/dist/fetcher-cDrfwN-Y.d.cts +25 -0
  17. package/dist/fetcher-cDrfwN-Y.d.cts.map +1 -0
  18. package/dist/fetcher.d.cts +3 -25
  19. package/dist/fetcher.d.mts +3 -25
  20. package/dist/index.cjs +8 -0
  21. package/dist/index.d.cts +5 -0
  22. package/dist/index.d.mts +5 -0
  23. package/dist/index.mjs +6 -0
  24. package/dist/infer-6KKCgmg1.cjs +0 -0
  25. package/{src/infer.ts → dist/infer-DfRq5kIb.d.cts} +54 -83
  26. package/dist/infer-DfRq5kIb.d.cts.map +1 -0
  27. package/dist/infer-bTirNeNW.d.mts +133 -0
  28. package/dist/infer-bTirNeNW.d.mts.map +1 -0
  29. package/dist/infer-uCUq1whM.mjs +0 -0
  30. package/dist/infer.cjs +1 -0
  31. package/dist/infer.d.cts +2 -133
  32. package/dist/infer.d.mts +2 -133
  33. package/dist/infer.mjs +1 -0
  34. package/dist/openapi-hooks.cjs.map +1 -1
  35. package/dist/openapi-hooks.d.cts.map +1 -1
  36. package/dist/openapi-hooks.d.mts +1 -1
  37. package/dist/openapi-hooks.d.mts.map +1 -1
  38. package/dist/openapi-hooks.mjs.map +1 -1
  39. package/dist/react-query.d.mts +1 -1
  40. package/dist/types-BH8WgGrm.mjs +0 -0
  41. package/dist/{types-D8Jrl4o3.d.mts → types-BMGM6sZc.d.mts} +1 -1
  42. package/dist/{types-D8Jrl4o3.d.mts.map → types-BMGM6sZc.d.mts.map} +1 -1
  43. package/dist/types-a8gm_IaQ.cjs +0 -0
  44. package/dist/types.cjs +1 -0
  45. package/dist/types.d.mts +1 -1
  46. package/dist/types.mjs +1 -0
  47. package/package.json +8 -5
  48. package/CHANGELOG.md +0 -146
  49. package/dist/auth-fetcher.cjs.map +0 -1
  50. package/dist/auth-fetcher.d.cts.map +0 -1
  51. package/dist/auth-fetcher.d.mts.map +0 -1
  52. package/dist/auth-fetcher.mjs.map +0 -1
  53. package/dist/fetcher.d.cts.map +0 -1
  54. package/dist/fetcher.d.mts.map +0 -1
  55. package/dist/infer.d.cts.map +0 -1
  56. package/dist/infer.d.mts.map +0 -1
  57. package/src/__tests__/auth-fetcher.spec.ts +0 -505
  58. package/src/__tests__/endpoint-hooks.spec.tsx +0 -374
  59. package/src/__tests__/fetcher.spec.ts +0 -580
  60. package/src/__tests__/infer.integration.spec.ts +0 -188
  61. package/src/__tests__/infer.spec.ts +0 -189
  62. package/src/__tests__/method-restrictions.spec.tsx +0 -227
  63. package/src/__tests__/mutation-inference.spec.tsx +0 -343
  64. package/src/__tests__/openapi-hooks.spec.tsx +0 -557
  65. package/src/__tests__/react-query-infinite.spec.tsx +0 -1003
  66. package/src/__tests__/react-query-invalidation.spec.tsx +0 -239
  67. package/src/__tests__/react-query.spec.tsx +0 -582
  68. package/src/__tests__/setup.ts +0 -281
  69. package/src/__tests__/types.spec.ts +0 -134
  70. package/src/__tests__/url-parsing.spec.ts +0 -196
  71. package/src/auth-fetcher.ts +0 -288
  72. package/src/endpoint-hooks.ts +0 -346
  73. package/src/fetcher.ts +0 -171
  74. package/src/openapi-hooks.ts +0 -193
  75. package/src/openapi-types.d.ts +0 -440
  76. package/src/openapi.json +0 -595
  77. package/src/react-query.ts +0 -341
  78. package/src/types.ts +0 -226
  79. package/tsconfig.json +0 -12
@@ -1,557 +0,0 @@
1
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
2
- /**
3
- * @vitest-environment jsdom
4
- */
5
- import { renderHook, waitFor } from '@testing-library/react';
6
- import { afterEach, describe, expect, it, vi } from 'vitest';
7
- import { createOpenAPIHooks } from '../openapi-hooks';
8
- import './setup';
9
-
10
- // Test OpenAPI types
11
- interface TestPaths {
12
- '/users': {
13
- get: {
14
- operationId: 'listUsers';
15
- parameters?: {
16
- query?: {
17
- page?: number;
18
- limit?: number;
19
- search?: string;
20
- };
21
- };
22
- responses: {
23
- 200: {
24
- content: {
25
- 'application/json': {
26
- users: Array<{
27
- id: string;
28
- name: string;
29
- email: string;
30
- }>;
31
- total: number;
32
- };
33
- };
34
- };
35
- };
36
- };
37
- post: {
38
- operationId: 'createUser';
39
- requestBody: {
40
- content: {
41
- 'application/json': {
42
- name: string;
43
- email: string;
44
- password: string;
45
- };
46
- };
47
- };
48
- responses: {
49
- 201: {
50
- content: {
51
- 'application/json': {
52
- id: string;
53
- name: string;
54
- email: string;
55
- };
56
- };
57
- };
58
- };
59
- };
60
- };
61
- '/users/{id}': {
62
- parameters: {
63
- path: {
64
- id: string;
65
- };
66
- };
67
- get: {
68
- operationId: 'getUser';
69
- responses: {
70
- 200: {
71
- content: {
72
- 'application/json': {
73
- id: string;
74
- name: string;
75
- email: string;
76
- createdAt: string;
77
- };
78
- };
79
- };
80
- };
81
- };
82
- patch: {
83
- operationId: 'updateUser';
84
- requestBody: {
85
- content: {
86
- 'application/json': {
87
- name?: string;
88
- email?: string;
89
- };
90
- };
91
- };
92
- responses: {
93
- 200: {
94
- content: {
95
- 'application/json': {
96
- id: string;
97
- name: string;
98
- email: string;
99
- };
100
- };
101
- };
102
- };
103
- };
104
- delete: {
105
- operationId: 'deleteUser';
106
- responses: {
107
- 204: {};
108
- };
109
- };
110
- };
111
- '/posts/{postId}': {
112
- get: {
113
- operationId: 'getPost';
114
- parameters: {
115
- path: {
116
- postId: string;
117
- };
118
- query?: {
119
- includeAuthor?: boolean;
120
- };
121
- };
122
- responses: {
123
- 200: {
124
- content: {
125
- 'application/json': {
126
- id: string;
127
- title: string;
128
- content: string;
129
- authorId: string;
130
- author?: {
131
- id: string;
132
- name: string;
133
- };
134
- };
135
- };
136
- };
137
- };
138
- };
139
- };
140
- }
141
-
142
- // Note: fetch is mocked by MSW in setup.ts
143
-
144
- // Test wrapper
145
- function createWrapper() {
146
- const queryClient = new QueryClient({
147
- defaultOptions: {
148
- queries: { retry: false },
149
- mutations: { retry: false },
150
- },
151
- });
152
-
153
- return ({ children }: { children: any }) => (
154
- <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
155
- );
156
- }
157
-
158
- describe('createOpenAPIHooks', () => {
159
- const operations = {
160
- listUsers: { path: '/users', method: 'get' },
161
- createUser: { path: '/users', method: 'post' },
162
- getUser: { path: '/users/{id}', method: 'get' },
163
- updateUser: { path: '/users/{id}', method: 'patch' },
164
- deleteUser: { path: '/users/{id}', method: 'delete' },
165
- getPost: { path: '/posts/{postId}', method: 'get' },
166
- };
167
-
168
- afterEach(() => {
169
- vi.clearAllMocks();
170
- });
171
-
172
- describe('useQuery', () => {
173
- it('should fetch data for simple GET operation', async () => {
174
- // MSW will return the predefined response from setup.ts
175
-
176
- const api = createOpenAPIHooks<TestPaths>({
177
- baseURL: 'https://api.example.com',
178
- operations,
179
- });
180
-
181
- const { result } = renderHook(() => api.useQuery('listUsers'), {
182
- wrapper: createWrapper(),
183
- });
184
-
185
- await waitFor(() => {
186
- expect(result.current.isSuccess).toBe(true);
187
- });
188
-
189
- expect(result.current.data).toEqual({
190
- users: [
191
- { id: '1', name: 'John Doe', email: 'john@example.com' },
192
- { id: '2', name: 'Jane Smith', email: 'jane@example.com' },
193
- ],
194
- });
195
- });
196
-
197
- it('should handle query parameters', async () => {
198
- // MSW will return the predefined response from setup.ts
199
-
200
- const api = createOpenAPIHooks<TestPaths>({
201
- baseURL: 'https://api.example.com',
202
- operations,
203
- });
204
-
205
- const { result } = renderHook(
206
- () =>
207
- api.useQuery('listUsers', {
208
- // query: { page: 2, limit: 10, search: 'john' },
209
- }),
210
- { wrapper: createWrapper() },
211
- );
212
-
213
- await waitFor(() => {
214
- expect(result.current.isSuccess).toBe(true);
215
- });
216
-
217
- // Query parameters are handled by MSW, verify data structure
218
- expect(result.current.data).toBeDefined();
219
- });
220
-
221
- it('should handle path parameters', async () => {
222
- // MSW will return the predefined response from setup.ts
223
-
224
- const api = createOpenAPIHooks<TestPaths>({
225
- baseURL: 'https://api.example.com',
226
- operations,
227
- });
228
-
229
- const { result } = renderHook(
230
- () =>
231
- api.useQuery('getUser', {
232
- params: { id: '123' },
233
- }),
234
- { wrapper: createWrapper() },
235
- );
236
-
237
- await waitFor(() => {
238
- expect(result.current.isSuccess).toBe(true);
239
- });
240
-
241
- expect(result.current.data).toEqual({
242
- id: '123',
243
- name: 'John Doe',
244
- email: 'john@example.com',
245
- });
246
- });
247
-
248
- it('should handle both path and query parameters', async () => {
249
- // MSW will return the predefined response from setup.ts
250
-
251
- const api = createOpenAPIHooks<TestPaths>({
252
- baseURL: 'https://api.example.com',
253
- operations,
254
- });
255
-
256
- const { result } = renderHook(
257
- () =>
258
- api.useQuery('getPost', {
259
- params: { postId: '456' },
260
- query: { includeAuthor: true },
261
- }),
262
- { wrapper: createWrapper() },
263
- );
264
-
265
- await waitFor(() => {
266
- expect(result.current.isSuccess).toBe(true);
267
- });
268
-
269
- expect(result.current.data).toEqual({
270
- id: '456',
271
- title: 'Test Post',
272
- content: 'Test content',
273
- authorId: '123',
274
- author: { id: '123', name: 'John' },
275
- });
276
- });
277
-
278
- it('should use proper query key for caching', async () => {
279
- // MSW will handle the responses
280
-
281
- const api = createOpenAPIHooks<TestPaths>({
282
- baseURL: 'https://api.example.com',
283
- operations,
284
- });
285
-
286
- const { result: result1 } = renderHook(
287
- () =>
288
- api.useQuery('listUsers', {
289
- query: { page: 1 },
290
- }),
291
- { wrapper: createWrapper() },
292
- );
293
-
294
- const { result: result2 } = renderHook(
295
- () =>
296
- api.useQuery('listUsers', {
297
- query: { page: 1 },
298
- }),
299
- { wrapper: createWrapper() },
300
- );
301
-
302
- await waitFor(() => {
303
- expect(result1.current.isSuccess).toBe(true);
304
- expect(result2.current.isSuccess).toBe(true);
305
- });
306
-
307
- // Both queries should have the same data due to caching
308
- expect(result1.current.data).toEqual(result2.current.data);
309
- });
310
- });
311
-
312
- describe('useMutation', () => {
313
- it('should handle POST mutation', async () => {
314
- // MSW will return the predefined response from setup.ts
315
-
316
- const api = createOpenAPIHooks<TestPaths>({
317
- baseURL: 'https://api.example.com',
318
- operations,
319
- });
320
-
321
- const { result } = renderHook(() => api.useMutation('createUser'), {
322
- wrapper: createWrapper(),
323
- });
324
-
325
- result.current.mutate({
326
- body: {
327
- name: 'New User',
328
- email: 'new@example.com',
329
- password: 'secret123',
330
- },
331
- });
332
-
333
- await waitFor(() => {
334
- expect(result.current.isSuccess).toBe(true);
335
- });
336
-
337
- expect(result.current.data).toEqual({
338
- id: '123',
339
- name: 'New User',
340
- email: 'new@example.com',
341
- });
342
- });
343
-
344
- it('should handle PATCH mutation with path params', async () => {
345
- // MSW will return the predefined response from setup.ts
346
-
347
- const api = createOpenAPIHooks<TestPaths>({
348
- baseURL: 'https://api.example.com',
349
- operations,
350
- });
351
-
352
- const { result } = renderHook(() => api.useMutation('updateUser'), {
353
- wrapper: createWrapper(),
354
- });
355
-
356
- result.current.mutate({
357
- params: { id: '123' },
358
- body: { name: 'Updated Name' },
359
- });
360
-
361
- await waitFor(() => {
362
- expect(result.current.isSuccess).toBe(true);
363
- });
364
-
365
- expect(result.current.data).toEqual({
366
- id: '123',
367
- name: 'Updated Name',
368
- email: 'john@example.com',
369
- });
370
- });
371
-
372
- it('should handle DELETE mutation returning void', async () => {
373
- // MSW will return 204 No Content for DELETE
374
-
375
- const api = createOpenAPIHooks<TestPaths>({
376
- baseURL: 'https://api.example.com',
377
- operations,
378
- });
379
-
380
- const { result } = renderHook(() => api.useMutation('deleteUser'), {
381
- wrapper: createWrapper(),
382
- });
383
-
384
- result.current.mutate({
385
- params: { id: '123' },
386
- });
387
-
388
- await waitFor(() => {
389
- expect(result.current.isSuccess).toBe(true);
390
- });
391
-
392
- expect(result.current.data).toBeUndefined();
393
- });
394
-
395
- it('should handle mutation options', async () => {
396
- // MSW will handle the response
397
-
398
- const onSuccess = vi.fn();
399
- const onError = vi.fn();
400
-
401
- const api = createOpenAPIHooks<TestPaths>({
402
- baseURL: 'https://api.example.com',
403
- operations,
404
- });
405
-
406
- const { result } = renderHook(
407
- () =>
408
- api.useMutation('createUser', {
409
- onSuccess,
410
- onError,
411
- }),
412
- { wrapper: createWrapper() },
413
- );
414
-
415
- result.current.mutate({
416
- body: {
417
- name: 'Test',
418
- email: 'test@test.com',
419
- password: 'password',
420
- },
421
- });
422
-
423
- await waitFor(() => {
424
- expect(result.current.isSuccess).toBe(true);
425
- });
426
-
427
- expect(onSuccess).toHaveBeenCalled();
428
- expect(onSuccess.mock.calls[0]?.[0]).toEqual({
429
- id: '123',
430
- name: 'Test',
431
- email: 'test@test.com',
432
- });
433
- expect(onError).not.toHaveBeenCalled();
434
- });
435
- });
436
-
437
- describe('buildEndpoint', () => {
438
- it('should use operation registry when provided', () => {
439
- const api = createOpenAPIHooks<TestPaths>({
440
- baseURL: 'https://api.example.com',
441
- operations,
442
- });
443
-
444
- // The endpoint should be built correctly based on the registry
445
- const { result } = renderHook(() => api.useQuery('listUsers'), {
446
- wrapper: createWrapper(),
447
- });
448
-
449
- // Wait for the query to be initiated
450
- expect(result.current.isLoading).toBe(true);
451
- });
452
-
453
- it('should work without operation registry', () => {
454
- const api = createOpenAPIHooks<TestPaths>({
455
- baseURL: 'https://api.example.com',
456
- });
457
-
458
- // Without registry, it should use operationId as fallback
459
- const { result } = renderHook(() => api.useQuery('listUsers'), {
460
- wrapper: createWrapper(),
461
- });
462
-
463
- expect(result.current.isLoading).toBe(true);
464
- });
465
- });
466
-
467
- describe('type inference', () => {
468
- it('should infer correct response types', () => {
469
- const api = createOpenAPIHooks<TestPaths>({
470
- baseURL: 'https://api.example.com',
471
- operations,
472
- });
473
-
474
- const { result } = renderHook(() => api.useQuery('listUsers'), {
475
- wrapper: createWrapper(),
476
- });
477
-
478
- // Type test - this should compile without errors
479
- if (result.current.data) {
480
- const users: Array<{ id: string; name: string; email: string }> =
481
- result.current.data.users;
482
- const total: number = result.current.data.total;
483
- expect(users).toBeDefined();
484
- expect(total).toBeDefined();
485
- }
486
- });
487
-
488
- it('should enforce required parameters', () => {
489
- const api = createOpenAPIHooks<TestPaths>({
490
- baseURL: 'https://api.example.com',
491
- operations,
492
- });
493
-
494
- // This test is about type checking, not runtime behavior
495
- // The TypeScript compiler enforces these constraints:
496
-
497
- // ✓ This compiles - no params required for listUsers
498
- const listUsersHook = () => api.useQuery('listUsers');
499
-
500
- // ✓ This compiles - params are provided for getUser
501
- const getUserHook = () =>
502
- api.useQuery('getUser', { params: { id: '123' } });
503
-
504
- // ✗ This would not compile - missing required params
505
- // const invalidHook = () => api.useQuery('getUser');
506
-
507
- expect(listUsersHook).toBeDefined();
508
- expect(getUserHook).toBeDefined();
509
- });
510
-
511
- it('should handle optional parameters correctly', () => {
512
- const api = createOpenAPIHooks<TestPaths>({
513
- baseURL: 'https://api.example.com',
514
- operations,
515
- });
516
-
517
- // All valid ways to call listUsers - wrapped in functions
518
- const hook1 = () => api.useQuery('listUsers');
519
- const hook2 = () => api.useQuery('listUsers', {});
520
- const hook3 = () => api.useQuery('listUsers', { query: {} });
521
- const hook4 = () => api.useQuery('listUsers', { query: { page: 1 } });
522
- const hook5 = () =>
523
- api.useQuery('listUsers', { query: { page: 1, limit: 10 } });
524
-
525
- expect(hook1).toBeDefined();
526
- expect(hook2).toBeDefined();
527
- expect(hook3).toBeDefined();
528
- expect(hook4).toBeDefined();
529
- expect(hook5).toBeDefined();
530
- });
531
- });
532
-
533
- describe('error handling', () => {
534
- it.skip('should handle fetch errors', async () => {
535
- // This test is skipped because we need a way to trigger actual fetch errors
536
- // The current implementation always returns successful responses from MSW
537
- });
538
-
539
- it('should handle non-ok responses', async () => {
540
- // MSW will return 404 for user id '404'
541
-
542
- const api = createOpenAPIHooks<TestPaths>({
543
- baseURL: 'https://api.example.com',
544
- operations,
545
- });
546
-
547
- const { result } = renderHook(
548
- () => api.useQuery('getUser', { params: { id: '404' } }),
549
- { wrapper: createWrapper() },
550
- );
551
-
552
- await waitFor(() => {
553
- expect(result.current.isError).toBe(true);
554
- });
555
- });
556
- });
557
- });