@geekmidas/client 0.4.0 → 1.0.0

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 (72) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/auth-fetcher.cjs +0 -1
  3. package/dist/auth-fetcher.cjs.map +1 -1
  4. package/dist/auth-fetcher.d.cts +1 -1
  5. package/dist/auth-fetcher.d.cts.map +1 -1
  6. package/dist/auth-fetcher.d.mts +1 -1
  7. package/dist/auth-fetcher.d.mts.map +1 -1
  8. package/dist/auth-fetcher.mjs +0 -1
  9. package/dist/auth-fetcher.mjs.map +1 -1
  10. package/dist/endpoint-hooks.cjs +10 -5
  11. package/dist/endpoint-hooks.cjs.map +1 -1
  12. package/dist/endpoint-hooks.d.cts +2 -2
  13. package/dist/endpoint-hooks.d.cts.map +1 -1
  14. package/dist/endpoint-hooks.d.mts +2 -2
  15. package/dist/endpoint-hooks.d.mts.map +1 -1
  16. package/dist/endpoint-hooks.mjs +10 -5
  17. package/dist/endpoint-hooks.mjs.map +1 -1
  18. package/dist/fetcher-5fnBE7Dk.mjs.map +1 -1
  19. package/dist/fetcher-CgLEaIAC.cjs.map +1 -1
  20. package/dist/fetcher.d.cts +1 -1
  21. package/dist/fetcher.d.cts.map +1 -1
  22. package/dist/fetcher.d.mts +1 -1
  23. package/dist/fetcher.d.mts.map +1 -1
  24. package/dist/infer.d.cts.map +1 -1
  25. package/dist/infer.d.mts.map +1 -1
  26. package/dist/openapi-hooks.cjs.map +1 -1
  27. package/dist/openapi-hooks.d.cts +2 -2
  28. package/dist/openapi-hooks.d.cts.map +1 -1
  29. package/dist/openapi-hooks.d.mts +5 -5
  30. package/dist/openapi-hooks.d.mts.map +1 -1
  31. package/dist/openapi-hooks.mjs.map +1 -1
  32. package/dist/openapi-types.d.cts.map +1 -1
  33. package/dist/openapi-types.d.mts.map +1 -1
  34. package/dist/openapi.cjs.map +1 -1
  35. package/dist/openapi.mjs.map +1 -1
  36. package/dist/react-query.cjs.map +1 -1
  37. package/dist/react-query.d.cts +1 -1
  38. package/dist/react-query.d.cts.map +1 -1
  39. package/dist/react-query.d.mts +8 -8
  40. package/dist/react-query.d.mts.map +1 -1
  41. package/dist/react-query.mjs.map +1 -1
  42. package/dist/{types-FxummKaL.d.mts → types-4K4N-Fl1.d.cts} +2 -2
  43. package/dist/types-4K4N-Fl1.d.cts.map +1 -0
  44. package/dist/{types-vutATyWv.d.cts → types-hhkZWjQn.d.mts} +2 -2
  45. package/dist/types-hhkZWjQn.d.mts.map +1 -0
  46. package/dist/types.d.cts +1 -1
  47. package/dist/types.d.mts +1 -1
  48. package/package.json +5 -5
  49. package/src/__tests__/auth-fetcher.spec.ts +476 -476
  50. package/src/__tests__/endpoint-hooks.spec.tsx +348 -348
  51. package/src/__tests__/fetcher.spec.ts +403 -403
  52. package/src/__tests__/infer.integration.spec.ts +171 -171
  53. package/src/__tests__/infer.spec.ts +182 -182
  54. package/src/__tests__/method-restrictions.spec.tsx +165 -165
  55. package/src/__tests__/openapi-hooks.spec.tsx +536 -536
  56. package/src/__tests__/react-query-infinite.spec.tsx +989 -989
  57. package/src/__tests__/react-query-invalidation.spec.tsx +223 -222
  58. package/src/__tests__/react-query.spec.tsx +567 -567
  59. package/src/__tests__/setup.ts +260 -260
  60. package/src/__tests__/types.spec.ts +127 -127
  61. package/src/__tests__/url-parsing.spec.ts +191 -191
  62. package/src/auth-fetcher.ts +160 -162
  63. package/src/endpoint-hooks.ts +151 -156
  64. package/src/fetcher.ts +163 -163
  65. package/src/infer.ts +64 -63
  66. package/src/openapi-hooks.ts +146 -146
  67. package/src/openapi-types.d.ts +428 -428
  68. package/src/openapi.json +593 -593
  69. package/src/react-query.ts +281 -281
  70. package/src/types.ts +121 -124
  71. package/dist/types-FxummKaL.d.mts.map +0 -1
  72. package/dist/types-vutATyWv.d.cts.map +0 -1
@@ -1,281 +1,281 @@
1
- import { http, HttpResponse } from 'msw';
1
+ import { HttpResponse, http } from 'msw';
2
2
  import { setupServer } from 'msw/node';
3
3
  import { afterAll, afterEach, beforeAll } from 'vitest';
4
4
 
5
5
  // Define request handlers
6
6
  export const handlers = [
7
- // GET /users
8
- http.get('https://api.example.com/users', () => {
9
- return HttpResponse.json({
10
- users: [
11
- { id: '1', name: 'John Doe', email: 'john@example.com' },
12
- { id: '2', name: 'Jane Smith', email: 'jane@example.com' },
13
- ],
14
- });
15
- }),
16
-
17
- // POST /users
18
- http.post('https://api.example.com/users', async ({ request }) => {
19
- const body = await request.json();
20
- return HttpResponse.json(
21
- {
22
- id: '123',
23
- name: (body as any).name,
24
- email: (body as any).email,
25
- },
26
- { status: 201 },
27
- );
28
- }),
29
-
30
- // GET /users/{id}
31
- http.get('https://api.example.com/users/:id', ({ params }) => {
32
- const { id } = params;
33
- if (id === '404') {
34
- return HttpResponse.json({ message: 'User not found' }, { status: 404 });
35
- }
36
- return HttpResponse.json({
37
- id,
38
- name: 'John Doe',
39
- email: 'john@example.com',
40
- });
41
- }),
42
-
43
- // PUT /users/{id}
44
- http.put('https://api.example.com/users/:id', async ({ params, request }) => {
45
- const { id } = params;
46
- const body = await request.json();
47
- return HttpResponse.json({
48
- id,
49
- name: (body as any).name || 'John Doe',
50
- email: (body as any).email || 'john@example.com',
51
- });
52
- }),
53
-
54
- // PATCH /users/{id}
55
- http.patch(
56
- 'https://api.example.com/users/:id',
57
- async ({ params, request }) => {
58
- const { id } = params;
59
- const body = await request.json();
60
- return HttpResponse.json({
61
- id,
62
- name: (body as any).name || 'John Doe',
63
- email: (body as any).email || 'john@example.com',
64
- });
65
- },
66
- ),
67
-
68
- // DELETE /users/{id}
69
- http.delete('https://api.example.com/users/:id', () => {
70
- return new HttpResponse(null, { status: 204 });
71
- }),
72
-
73
- // GET /posts with query parameters
74
- http.get('https://api.example.com/posts', ({ request }) => {
75
- const url = new URL(request.url);
76
- const page = parseInt(url.searchParams.get('page') || '1');
77
- const limit = parseInt(url.searchParams.get('limit') || '10');
78
- const sort = url.searchParams.get('sort') || 'asc';
79
-
80
- // Generate posts based on page to simulate pagination
81
- const totalPosts = 50;
82
- const startIndex = (page - 1) * limit;
83
- const endIndex = Math.min(startIndex + limit, totalPosts);
84
-
85
- const posts = Array.from({ length: endIndex - startIndex }, (_, i) => ({
86
- id: `post-${startIndex + i + 1}`,
87
- title: `Test Post ${startIndex + i + 1}`,
88
- content: `Test content for post ${startIndex + i + 1}`,
89
- authorId: `author-${((startIndex + i) % 5) + 1}`,
90
- createdAt: new Date(
91
- Date.now() - (startIndex + i) * 3600000,
92
- ).toISOString(),
93
- }));
94
-
95
- return HttpResponse.json({
96
- posts,
97
- pagination: {
98
- page,
99
- limit,
100
- total: totalPosts,
101
- },
102
- sort,
103
- });
104
- }),
105
-
106
- // GET /posts/{postId}
107
- http.get('https://api.example.com/posts/:postId', ({ params, request }) => {
108
- const { postId } = params;
109
- const url = new URL(request.url);
110
- const includeAuthor = url.searchParams.get('includeAuthor') === 'true';
111
-
112
- const response = {
113
- id: postId,
114
- title: 'Test Post',
115
- content: 'Test content',
116
- authorId: '123',
117
- };
118
-
119
- if (includeAuthor) {
120
- return HttpResponse.json({
121
- ...response,
122
- author: { id: '123', name: 'John' },
123
- });
124
- }
125
-
126
- return HttpResponse.json(response);
127
- }),
128
-
129
- // Error endpoint for testing
130
- http.get('https://api.example.com/error', () => {
131
- return HttpResponse.json(
132
- { message: 'Internal server error' },
133
- { status: 500 },
134
- );
135
- }),
136
-
137
- // Unauthorized endpoint
138
- http.get('https://api.example.com/protected', ({ request }) => {
139
- const auth = request.headers.get('Authorization');
140
- if (!auth || !auth.includes('valid-token')) {
141
- return HttpResponse.json({ message: 'Unauthorized' }, { status: 401 });
142
- }
143
- return HttpResponse.json({ message: 'Protected data' });
144
- }),
145
-
146
- // Search endpoint
147
- http.get('https://api.example.com/search', ({ request }) => {
148
- const url = new URL(request.url);
149
- const tags = url.searchParams.getAll('tags');
150
- return HttpResponse.json({
151
- items: tags,
152
- results: tags.map((tag, i) => ({ id: i, tag })),
153
- });
154
- }),
155
-
156
- // Products endpoint with filters
157
- http.get('https://api.example.com/products', ({ request }) => {
158
- const url = new URL(request.url);
159
- const params: Record<string, string> = {};
160
- url.searchParams.forEach((value, key) => {
161
- params[key] = value;
162
- });
163
- return HttpResponse.json({
164
- results: [],
165
- filters: params,
166
- });
167
- }),
168
-
169
- // Advanced search endpoint
170
- http.get('https://api.example.com/advanced-search', ({ request }) => {
171
- const url = new URL(request.url);
172
- const params: Record<string, string> = {};
173
- url.searchParams.forEach((value, key) => {
174
- params[key] = value;
175
- });
176
- return HttpResponse.json({
177
- results: [],
178
- query: params,
179
- });
180
- }),
181
-
182
- // Paginated users endpoint for infinite queries
183
- http.get('https://api.example.com/users/paginated', ({ request }) => {
184
- const url = new URL(request.url);
185
- const page = parseInt(url.searchParams.get('page') || '1');
186
- const limit = parseInt(url.searchParams.get('limit') || '10');
187
-
188
- const allUsers = Array.from({ length: 50 }, (_, i) => ({
189
- id: `user-${i + 1}`,
190
- name: `User ${i + 1}`,
191
- email: `user${i + 1}@example.com`,
192
- }));
193
-
194
- const startIndex = (page - 1) * limit;
195
- const endIndex = startIndex + limit;
196
- const users = allUsers.slice(startIndex, endIndex);
197
- const hasMore = endIndex < allUsers.length;
198
-
199
- return HttpResponse.json({
200
- users,
201
- pagination: {
202
- page,
203
- limit,
204
- total: allUsers.length,
205
- hasMore,
206
- },
207
- });
208
- }),
209
-
210
- // Cursor-based pagination endpoint for infinite queries
211
- http.get('https://api.example.com/messages', ({ request }) => {
212
- const url = new URL(request.url);
213
- const cursor = url.searchParams.get('cursor');
214
- const limit = parseInt(url.searchParams.get('limit') || '10');
215
-
216
- const allMessages = Array.from({ length: 100 }, (_, i) => ({
217
- id: `msg-${i + 1}`,
218
- text: `Message ${i + 1}`,
219
- timestamp: new Date(Date.now() - i * 60000).toISOString(),
220
- }));
221
-
222
- let startIndex = 0;
223
- if (cursor) {
224
- const cursorIndex = allMessages.findIndex((m) => m.id === cursor);
225
- startIndex = cursorIndex !== -1 ? cursorIndex + 1 : 0;
226
- }
227
-
228
- const messages = allMessages.slice(startIndex, startIndex + limit);
229
- const nextCursor =
230
- messages.length === limit ? messages[messages.length - 1].id : null;
231
-
232
- return HttpResponse.json({
233
- messages,
234
- nextCursor,
235
- });
236
- }),
237
-
238
- // Echo endpoint that returns all query parameters
239
- http.get('https://api.example.com/echo', ({ request }) => {
240
- const url = new URL(request.url);
241
- const queryParams: Record<string, string> = {};
242
-
243
- // Collect all query parameters
244
- url.searchParams.forEach((value, key) => {
245
- queryParams[key] = value;
246
- });
247
-
248
- return HttpResponse.json({
249
- queryParams,
250
- // Also include some pagination data for infinite query testing
251
- data: Array.from({ length: 5 }, (_, i) => ({
252
- id: `item-${i + 1}`,
253
- value: `Value ${i + 1}`,
254
- })),
255
- pagination: {
256
- page: parseInt(queryParams.page || '1'),
257
- limit: parseInt(queryParams.limit || '10'),
258
- total: 50,
259
- hasMore: parseInt(queryParams.page || '1') < 5,
260
- },
261
- });
262
- }),
7
+ // GET /users
8
+ http.get('https://api.example.com/users', () => {
9
+ return HttpResponse.json({
10
+ users: [
11
+ { id: '1', name: 'John Doe', email: 'john@example.com' },
12
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com' },
13
+ ],
14
+ });
15
+ }),
16
+
17
+ // POST /users
18
+ http.post('https://api.example.com/users', async ({ request }) => {
19
+ const body = await request.json();
20
+ return HttpResponse.json(
21
+ {
22
+ id: '123',
23
+ name: (body as any).name,
24
+ email: (body as any).email,
25
+ },
26
+ { status: 201 },
27
+ );
28
+ }),
29
+
30
+ // GET /users/{id}
31
+ http.get('https://api.example.com/users/:id', ({ params }) => {
32
+ const { id } = params;
33
+ if (id === '404') {
34
+ return HttpResponse.json({ message: 'User not found' }, { status: 404 });
35
+ }
36
+ return HttpResponse.json({
37
+ id,
38
+ name: 'John Doe',
39
+ email: 'john@example.com',
40
+ });
41
+ }),
42
+
43
+ // PUT /users/{id}
44
+ http.put('https://api.example.com/users/:id', async ({ params, request }) => {
45
+ const { id } = params;
46
+ const body = await request.json();
47
+ return HttpResponse.json({
48
+ id,
49
+ name: (body as any).name || 'John Doe',
50
+ email: (body as any).email || 'john@example.com',
51
+ });
52
+ }),
53
+
54
+ // PATCH /users/{id}
55
+ http.patch(
56
+ 'https://api.example.com/users/:id',
57
+ async ({ params, request }) => {
58
+ const { id } = params;
59
+ const body = await request.json();
60
+ return HttpResponse.json({
61
+ id,
62
+ name: (body as any).name || 'John Doe',
63
+ email: (body as any).email || 'john@example.com',
64
+ });
65
+ },
66
+ ),
67
+
68
+ // DELETE /users/{id}
69
+ http.delete('https://api.example.com/users/:id', () => {
70
+ return new HttpResponse(null, { status: 204 });
71
+ }),
72
+
73
+ // GET /posts with query parameters
74
+ http.get('https://api.example.com/posts', ({ request }) => {
75
+ const url = new URL(request.url);
76
+ const page = parseInt(url.searchParams.get('page') || '1', 10);
77
+ const limit = parseInt(url.searchParams.get('limit') || '10', 10);
78
+ const sort = url.searchParams.get('sort') || 'asc';
79
+
80
+ // Generate posts based on page to simulate pagination
81
+ const totalPosts = 50;
82
+ const startIndex = (page - 1) * limit;
83
+ const endIndex = Math.min(startIndex + limit, totalPosts);
84
+
85
+ const posts = Array.from({ length: endIndex - startIndex }, (_, i) => ({
86
+ id: `post-${startIndex + i + 1}`,
87
+ title: `Test Post ${startIndex + i + 1}`,
88
+ content: `Test content for post ${startIndex + i + 1}`,
89
+ authorId: `author-${((startIndex + i) % 5) + 1}`,
90
+ createdAt: new Date(
91
+ Date.now() - (startIndex + i) * 3600000,
92
+ ).toISOString(),
93
+ }));
94
+
95
+ return HttpResponse.json({
96
+ posts,
97
+ pagination: {
98
+ page,
99
+ limit,
100
+ total: totalPosts,
101
+ },
102
+ sort,
103
+ });
104
+ }),
105
+
106
+ // GET /posts/{postId}
107
+ http.get('https://api.example.com/posts/:postId', ({ params, request }) => {
108
+ const { postId } = params;
109
+ const url = new URL(request.url);
110
+ const includeAuthor = url.searchParams.get('includeAuthor') === 'true';
111
+
112
+ const response = {
113
+ id: postId,
114
+ title: 'Test Post',
115
+ content: 'Test content',
116
+ authorId: '123',
117
+ };
118
+
119
+ if (includeAuthor) {
120
+ return HttpResponse.json({
121
+ ...response,
122
+ author: { id: '123', name: 'John' },
123
+ });
124
+ }
125
+
126
+ return HttpResponse.json(response);
127
+ }),
128
+
129
+ // Error endpoint for testing
130
+ http.get('https://api.example.com/error', () => {
131
+ return HttpResponse.json(
132
+ { message: 'Internal server error' },
133
+ { status: 500 },
134
+ );
135
+ }),
136
+
137
+ // Unauthorized endpoint
138
+ http.get('https://api.example.com/protected', ({ request }) => {
139
+ const auth = request.headers.get('Authorization');
140
+ if (!auth || !auth.includes('valid-token')) {
141
+ return HttpResponse.json({ message: 'Unauthorized' }, { status: 401 });
142
+ }
143
+ return HttpResponse.json({ message: 'Protected data' });
144
+ }),
145
+
146
+ // Search endpoint
147
+ http.get('https://api.example.com/search', ({ request }) => {
148
+ const url = new URL(request.url);
149
+ const tags = url.searchParams.getAll('tags');
150
+ return HttpResponse.json({
151
+ items: tags,
152
+ results: tags.map((tag, i) => ({ id: i, tag })),
153
+ });
154
+ }),
155
+
156
+ // Products endpoint with filters
157
+ http.get('https://api.example.com/products', ({ request }) => {
158
+ const url = new URL(request.url);
159
+ const params: Record<string, string> = {};
160
+ url.searchParams.forEach((value, key) => {
161
+ params[key] = value;
162
+ });
163
+ return HttpResponse.json({
164
+ results: [],
165
+ filters: params,
166
+ });
167
+ }),
168
+
169
+ // Advanced search endpoint
170
+ http.get('https://api.example.com/advanced-search', ({ request }) => {
171
+ const url = new URL(request.url);
172
+ const params: Record<string, string> = {};
173
+ url.searchParams.forEach((value, key) => {
174
+ params[key] = value;
175
+ });
176
+ return HttpResponse.json({
177
+ results: [],
178
+ query: params,
179
+ });
180
+ }),
181
+
182
+ // Paginated users endpoint for infinite queries
183
+ http.get('https://api.example.com/users/paginated', ({ request }) => {
184
+ const url = new URL(request.url);
185
+ const page = parseInt(url.searchParams.get('page') || '1', 10);
186
+ const limit = parseInt(url.searchParams.get('limit') || '10', 10);
187
+
188
+ const allUsers = Array.from({ length: 50 }, (_, i) => ({
189
+ id: `user-${i + 1}`,
190
+ name: `User ${i + 1}`,
191
+ email: `user${i + 1}@example.com`,
192
+ }));
193
+
194
+ const startIndex = (page - 1) * limit;
195
+ const endIndex = startIndex + limit;
196
+ const users = allUsers.slice(startIndex, endIndex);
197
+ const hasMore = endIndex < allUsers.length;
198
+
199
+ return HttpResponse.json({
200
+ users,
201
+ pagination: {
202
+ page,
203
+ limit,
204
+ total: allUsers.length,
205
+ hasMore,
206
+ },
207
+ });
208
+ }),
209
+
210
+ // Cursor-based pagination endpoint for infinite queries
211
+ http.get('https://api.example.com/messages', ({ request }) => {
212
+ const url = new URL(request.url);
213
+ const cursor = url.searchParams.get('cursor');
214
+ const limit = parseInt(url.searchParams.get('limit') || '10', 10);
215
+
216
+ const allMessages = Array.from({ length: 100 }, (_, i) => ({
217
+ id: `msg-${i + 1}`,
218
+ text: `Message ${i + 1}`,
219
+ timestamp: new Date(Date.now() - i * 60000).toISOString(),
220
+ }));
221
+
222
+ let startIndex = 0;
223
+ if (cursor) {
224
+ const cursorIndex = allMessages.findIndex((m) => m.id === cursor);
225
+ startIndex = cursorIndex !== -1 ? cursorIndex + 1 : 0;
226
+ }
227
+
228
+ const messages = allMessages.slice(startIndex, startIndex + limit);
229
+ const nextCursor =
230
+ messages.length === limit ? messages[messages.length - 1].id : null;
231
+
232
+ return HttpResponse.json({
233
+ messages,
234
+ nextCursor,
235
+ });
236
+ }),
237
+
238
+ // Echo endpoint that returns all query parameters
239
+ http.get('https://api.example.com/echo', ({ request }) => {
240
+ const url = new URL(request.url);
241
+ const queryParams: Record<string, string> = {};
242
+
243
+ // Collect all query parameters
244
+ url.searchParams.forEach((value, key) => {
245
+ queryParams[key] = value;
246
+ });
247
+
248
+ return HttpResponse.json({
249
+ queryParams,
250
+ // Also include some pagination data for infinite query testing
251
+ data: Array.from({ length: 5 }, (_, i) => ({
252
+ id: `item-${i + 1}`,
253
+ value: `Value ${i + 1}`,
254
+ })),
255
+ pagination: {
256
+ page: parseInt(queryParams.page || '1', 10),
257
+ limit: parseInt(queryParams.limit || '10', 10),
258
+ total: 50,
259
+ hasMore: parseInt(queryParams.page || '1', 10) < 5,
260
+ },
261
+ });
262
+ }),
263
263
  ];
264
264
 
265
265
  export const server = setupServer(...handlers);
266
266
 
267
267
  // Establish API mocking before all tests
268
268
  beforeAll(() => {
269
- server.listen({ onUnhandledRequest: 'error' });
269
+ server.listen({ onUnhandledRequest: 'error' });
270
270
  });
271
271
 
272
272
  // Reset any request handlers that we may add during the tests,
273
273
  // so they don't affect other tests
274
274
  afterEach(() => {
275
- server.resetHandlers();
275
+ server.resetHandlers();
276
276
  });
277
277
 
278
278
  // Clean up after the tests are finished
279
279
  afterAll(() => {
280
- server.close();
280
+ server.close();
281
281
  });