@geekmidas/client 0.4.0 → 0.5.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.
- package/dist/auth-fetcher.cjs +0 -1
- package/dist/auth-fetcher.cjs.map +1 -1
- package/dist/auth-fetcher.d.cts +1 -1
- package/dist/auth-fetcher.d.cts.map +1 -1
- package/dist/auth-fetcher.d.mts +1 -1
- package/dist/auth-fetcher.d.mts.map +1 -1
- package/dist/auth-fetcher.mjs +0 -1
- package/dist/auth-fetcher.mjs.map +1 -1
- package/dist/endpoint-hooks.cjs +10 -5
- package/dist/endpoint-hooks.cjs.map +1 -1
- package/dist/endpoint-hooks.d.cts +2 -2
- package/dist/endpoint-hooks.d.cts.map +1 -1
- package/dist/endpoint-hooks.d.mts +2 -2
- package/dist/endpoint-hooks.d.mts.map +1 -1
- package/dist/endpoint-hooks.mjs +10 -5
- package/dist/endpoint-hooks.mjs.map +1 -1
- package/dist/fetcher-5fnBE7Dk.mjs.map +1 -1
- package/dist/fetcher-CgLEaIAC.cjs.map +1 -1
- package/dist/fetcher.d.cts +1 -1
- package/dist/fetcher.d.cts.map +1 -1
- package/dist/fetcher.d.mts +1 -1
- package/dist/fetcher.d.mts.map +1 -1
- package/dist/infer.d.cts.map +1 -1
- package/dist/infer.d.mts.map +1 -1
- package/dist/openapi-hooks.cjs.map +1 -1
- package/dist/openapi-hooks.d.cts +2 -2
- package/dist/openapi-hooks.d.cts.map +1 -1
- package/dist/openapi-hooks.d.mts +2 -2
- package/dist/openapi-hooks.d.mts.map +1 -1
- package/dist/openapi-hooks.mjs.map +1 -1
- package/dist/openapi-types.d.cts.map +1 -1
- package/dist/openapi-types.d.mts.map +1 -1
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.mjs.map +1 -1
- package/dist/react-query.cjs.map +1 -1
- package/dist/react-query.d.cts +1 -1
- package/dist/react-query.d.cts.map +1 -1
- package/dist/react-query.d.mts +1 -1
- package/dist/react-query.d.mts.map +1 -1
- package/dist/react-query.mjs.map +1 -1
- package/dist/{types-FxummKaL.d.mts → types-4K4N-Fl1.d.cts} +2 -2
- package/dist/types-4K4N-Fl1.d.cts.map +1 -0
- package/dist/{types-vutATyWv.d.cts → types-hhkZWjQn.d.mts} +2 -2
- package/dist/types-hhkZWjQn.d.mts.map +1 -0
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +3 -3
- package/src/__tests__/auth-fetcher.spec.ts +476 -476
- package/src/__tests__/endpoint-hooks.spec.tsx +348 -348
- package/src/__tests__/fetcher.spec.ts +403 -403
- package/src/__tests__/infer.integration.spec.ts +171 -171
- package/src/__tests__/infer.spec.ts +182 -182
- package/src/__tests__/method-restrictions.spec.tsx +165 -165
- package/src/__tests__/openapi-hooks.spec.tsx +536 -536
- package/src/__tests__/react-query-infinite.spec.tsx +989 -989
- package/src/__tests__/react-query-invalidation.spec.tsx +223 -222
- package/src/__tests__/react-query.spec.tsx +567 -567
- package/src/__tests__/setup.ts +260 -260
- package/src/__tests__/types.spec.ts +127 -127
- package/src/__tests__/url-parsing.spec.ts +191 -191
- package/src/auth-fetcher.ts +160 -162
- package/src/endpoint-hooks.ts +151 -156
- package/src/fetcher.ts +163 -163
- package/src/infer.ts +64 -63
- package/src/openapi-hooks.ts +146 -146
- package/src/openapi-types.d.ts +428 -428
- package/src/openapi.json +593 -593
- package/src/react-query.ts +281 -281
- package/src/types.ts +121 -124
- package/dist/types-FxummKaL.d.mts.map +0 -1
- package/dist/types-vutATyWv.d.cts.map +0 -1
package/src/auth-fetcher.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { TypedFetcher } from './fetcher';
|
|
2
2
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
ExtractEndpointResponse,
|
|
4
|
+
FetcherOptions,
|
|
5
|
+
FilteredRequestConfig,
|
|
6
|
+
TypedApiFunction,
|
|
7
|
+
TypedEndpoint,
|
|
8
8
|
} from './types';
|
|
9
9
|
|
|
10
10
|
export type { FetcherOptions } from './types';
|
|
@@ -13,15 +13,15 @@ export type { FetcherOptions } from './types';
|
|
|
13
13
|
* Security scheme object matching OpenAPI 3.1 specification.
|
|
14
14
|
*/
|
|
15
15
|
export interface SecuritySchemeObject {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
type: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';
|
|
17
|
+
description?: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
in?: 'query' | 'header' | 'cookie';
|
|
20
|
+
scheme?: string;
|
|
21
|
+
bearerFormat?: string;
|
|
22
|
+
flows?: Record<string, unknown>;
|
|
23
|
+
openIdConnectUrl?: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -29,7 +29,7 @@ export interface SecuritySchemeObject {
|
|
|
29
29
|
* This gives us the union of scheme names that endpoints require.
|
|
30
30
|
*/
|
|
31
31
|
export type UsedSecuritySchemes<
|
|
32
|
-
|
|
32
|
+
EndpointAuth extends Record<string, string | null>,
|
|
33
33
|
> = NonNullable<EndpointAuth[keyof EndpointAuth]>;
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -37,48 +37,48 @@ export type UsedSecuritySchemes<
|
|
|
37
37
|
* Compatible with @geekmidas/auth TokenClient.
|
|
38
38
|
*/
|
|
39
39
|
export interface TokenProvider {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Get a valid access token, refreshing if necessary.
|
|
42
|
+
*/
|
|
43
|
+
getValidAccessToken(): Promise<string | null>;
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Create Authorization headers from the current token.
|
|
47
|
+
*/
|
|
48
|
+
createValidAuthHeaders(): Promise<Record<string, string>>;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Interface for API key providers.
|
|
53
53
|
*/
|
|
54
54
|
export interface ApiKeyProvider {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Get the API key value.
|
|
57
|
+
*/
|
|
58
|
+
getApiKey(): Promise<string> | string;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
* Interface for AWS SigV4 request signing.
|
|
63
63
|
*/
|
|
64
64
|
export interface AwsSigner {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Sign a request with AWS SigV4.
|
|
67
|
+
* @param url - The request URL
|
|
68
|
+
* @param init - The request init object
|
|
69
|
+
* @returns Headers to add to the request
|
|
70
|
+
*/
|
|
71
|
+
sign(url: string, init: RequestInit): Promise<Record<string, string>>;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Auth strategy configuration for a specific security scheme type.
|
|
76
76
|
*/
|
|
77
77
|
export type AuthStrategy =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
| { type: 'bearer'; tokenProvider: TokenProvider }
|
|
79
|
+
| { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }
|
|
80
|
+
| { type: 'iam'; signer: AwsSigner }
|
|
81
|
+
| { type: 'none' };
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Options for creating an auth-aware fetcher.
|
|
@@ -87,41 +87,41 @@ export type AuthStrategy =
|
|
|
87
87
|
* @template SecuritySchemes - Available security scheme definitions
|
|
88
88
|
*/
|
|
89
89
|
export interface AuthFetcherOptions<
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
EndpointAuth extends Record<string, string | null>,
|
|
91
|
+
SecuritySchemes extends Record<string, SecuritySchemeObject>,
|
|
92
92
|
> extends Omit<FetcherOptions, 'onRequest'> {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Runtime map of endpoints to their required auth scheme.
|
|
95
|
+
* Generated by `gkm openapi --ts`.
|
|
96
|
+
*/
|
|
97
|
+
endpointAuth: EndpointAuth;
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Security scheme definitions.
|
|
101
|
+
* Generated by `gkm openapi --ts`.
|
|
102
|
+
*/
|
|
103
|
+
securitySchemes: SecuritySchemes;
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Auth strategies for security schemes that are actually used.
|
|
107
|
+
* Only schemes referenced in endpointAuth are required.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }
|
|
112
|
+
* // Then authStrategies must include strategies for 'jwt' and 'iam'
|
|
113
|
+
* authStrategies: {
|
|
114
|
+
* jwt: { type: 'bearer', tokenProvider },
|
|
115
|
+
* iam: { type: 'iam', signer: awsSigner },
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
authStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Optional request interceptor (runs after auth headers are added).
|
|
123
|
+
*/
|
|
124
|
+
onRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/**
|
|
@@ -153,138 +153,136 @@ export interface AuthFetcherOptions<
|
|
|
153
153
|
* ```
|
|
154
154
|
*/
|
|
155
155
|
export function createAuthAwareFetcher<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
156
|
+
Paths,
|
|
157
|
+
EndpointAuth extends Record<string, string | null> = Record<
|
|
158
|
+
string,
|
|
159
|
+
string | null
|
|
160
|
+
>,
|
|
161
|
+
SecuritySchemes extends Record<string, SecuritySchemeObject> = Record<
|
|
162
|
+
string,
|
|
163
|
+
SecuritySchemeObject
|
|
164
|
+
>,
|
|
165
165
|
>(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {
|
|
167
|
+
baseURL: string;
|
|
168
|
+
},
|
|
169
169
|
): TypedApiFunction<Paths> {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
170
|
+
const {
|
|
171
|
+
endpointAuth,
|
|
172
|
+
securitySchemes,
|
|
173
|
+
authStrategies,
|
|
174
|
+
onRequest: userOnRequest,
|
|
175
|
+
...fetcherOptions
|
|
176
|
+
} = options;
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
178
|
+
// Create base fetcher with user's onRequest if provided
|
|
179
|
+
const baseFetcher = new TypedFetcher<Paths>({
|
|
180
|
+
...fetcherOptions,
|
|
181
|
+
onRequest: userOnRequest,
|
|
182
|
+
});
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
184
|
+
const fetcher = async <T extends TypedEndpoint<Paths>>(
|
|
185
|
+
endpoint: T,
|
|
186
|
+
config?: FilteredRequestConfig<Paths, T>,
|
|
187
|
+
): Promise<ExtractEndpointResponse<Paths, T>> => {
|
|
188
|
+
// Look up auth requirement for this endpoint
|
|
189
|
+
const schemeName = endpointAuth[endpoint as keyof EndpointAuth] as
|
|
190
|
+
| string
|
|
191
|
+
| null;
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
let authHeaders: Record<string, string> = {};
|
|
194
194
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
if (schemeName) {
|
|
196
|
+
const scheme = securitySchemes[schemeName as keyof SecuritySchemes];
|
|
197
|
+
// Since authStrategies is now required to have all used schemes,
|
|
198
|
+
// we can safely access it - TypeScript ensures the strategy exists
|
|
199
|
+
const strategy =
|
|
200
|
+
authStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
202
|
+
if (strategy && scheme) {
|
|
203
|
+
authHeaders = await resolveAuthHeaders(strategy, scheme);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
// Merge auth headers with config headers
|
|
208
|
+
const existingHeaders =
|
|
209
|
+
config && 'headers' in config && config.headers
|
|
210
|
+
? (config.headers as Record<string, string>)
|
|
211
|
+
: {};
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
213
|
+
const mergedConfig = {
|
|
214
|
+
...config,
|
|
215
|
+
headers: {
|
|
216
|
+
...authHeaders,
|
|
217
|
+
...existingHeaders,
|
|
218
|
+
},
|
|
219
|
+
} as unknown as FilteredRequestConfig<Paths, T>;
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
return baseFetcher.request(endpoint, mergedConfig);
|
|
222
|
+
};
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
return fetcher as TypedApiFunction<Paths>;
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
/**
|
|
228
228
|
* Resolves auth headers based on the strategy and scheme.
|
|
229
229
|
*/
|
|
230
230
|
async function resolveAuthHeaders(
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
strategy: AuthStrategy,
|
|
232
|
+
scheme: SecuritySchemeObject,
|
|
233
233
|
): Promise<Record<string, string>> {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
switch (strategy.type) {
|
|
235
|
+
case 'bearer': {
|
|
236
|
+
return strategy.tokenProvider.createValidAuthHeaders();
|
|
237
|
+
}
|
|
238
238
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
case 'apiKey': {
|
|
240
|
+
const apiKey = await strategy.apiKeyProvider.getApiKey();
|
|
241
|
+
const headerName = strategy.headerName || scheme.name || 'X-API-Key';
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
243
|
+
if (scheme.in === 'header' || !scheme.in) {
|
|
244
|
+
return { [headerName]: apiKey };
|
|
245
|
+
}
|
|
246
|
+
// Note: query and cookie API keys are handled differently
|
|
247
|
+
// For now, we only support header-based API keys
|
|
248
|
+
return {};
|
|
249
|
+
}
|
|
250
250
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
return {};
|
|
263
|
-
}
|
|
251
|
+
case 'iam': {
|
|
252
|
+
// IAM signing requires the full URL and request config
|
|
253
|
+
// This is a simplified version - full implementation would need
|
|
254
|
+
// access to the complete request
|
|
255
|
+
// For now, return empty - the actual signing should be done
|
|
256
|
+
// in a custom onRequest interceptor if needed
|
|
257
|
+
return {};
|
|
258
|
+
}
|
|
259
|
+
default:
|
|
260
|
+
return {};
|
|
261
|
+
}
|
|
264
262
|
}
|
|
265
263
|
|
|
266
264
|
/**
|
|
267
265
|
* Type helper to extract the security scheme ID from an endpoint.
|
|
268
266
|
*/
|
|
269
267
|
export type GetEndpointAuth<
|
|
270
|
-
|
|
271
|
-
|
|
268
|
+
EndpointAuth extends Record<string, string | null>,
|
|
269
|
+
Endpoint extends keyof EndpointAuth,
|
|
272
270
|
> = EndpointAuth[Endpoint];
|
|
273
271
|
|
|
274
272
|
/**
|
|
275
273
|
* Type helper to get all authenticated endpoints.
|
|
276
274
|
*/
|
|
277
275
|
export type AuthenticatedEndpoints<
|
|
278
|
-
|
|
276
|
+
EndpointAuth extends Record<string, string | null>,
|
|
279
277
|
> = {
|
|
280
|
-
|
|
278
|
+
[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? never : K;
|
|
281
279
|
}[keyof EndpointAuth];
|
|
282
280
|
|
|
283
281
|
/**
|
|
284
282
|
* Type helper to get all public endpoints.
|
|
285
283
|
*/
|
|
286
284
|
export type PublicEndpoints<
|
|
287
|
-
|
|
285
|
+
EndpointAuth extends Record<string, string | null>,
|
|
288
286
|
> = {
|
|
289
|
-
|
|
287
|
+
[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;
|
|
290
288
|
}[keyof EndpointAuth];
|