@geekmidas/client 10.0.0-alpha.19 → 10.0.0-alpha.20

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/README.md CHANGED
@@ -76,7 +76,7 @@ interface API {
76
76
  email: string;
77
77
  };
78
78
  };
79
- 'GET /users/:id': {
79
+ 'GET /users/{id}': {
80
80
  params: {
81
81
  id: string;
82
82
  };
@@ -102,7 +102,7 @@ const user = await api('POST /users', {
102
102
  });
103
103
  // user is typed as { id: string; name: string; email: string }
104
104
 
105
- const singleUser = await api('GET /users/:id', {
105
+ const singleUser = await api('GET /users/{id}', {
106
106
  params: { id: '123' }
107
107
  });
108
108
  // singleUser is typed as { id: string; name: string; email: string }
@@ -280,6 +280,26 @@ function CreateUser() {
280
280
  }
281
281
  ```
282
282
 
283
+ ### Method Calls
284
+
285
+ Every client also answers by method — the same request as
286
+ `api('POST /users', …)`, with the method as the call:
287
+
288
+ ```typescript
289
+ await api.get('/health'); // declares nothing → no second argument
290
+ await api.get('/users/{id}', { params: { id: '123' } }); // path params → argument required
291
+ await api.post('/users', { body: { name: 'Ada', email } }); // body → argument required
292
+ await api.get('/search', { query: { q: 'ada' } }); // required query key → required
293
+ await api.get('/users', { query: { page: 2 } }); // optional query → optional
294
+
295
+ await api.post('/users', { body: { name: 'Ada' } }); // ❌ `email` is missing
296
+ await api.get('/health', { body: {} }); // ❌ GET /health takes no body
297
+ await api.post('/health'); // ❌ /health has no POST
298
+ ```
299
+
300
+ The route autocompletes per method — only routes with a `POST` appear in
301
+ `api.post` — and the second argument has only the keys the endpoint declares.
302
+
283
303
  ### Type-Safe Config Requirements
284
304
 
285
305
  The generated client enforces config requirements at the type level:
@@ -395,14 +415,14 @@ Type-safe cache invalidation:
395
415
  await api.invalidateQueries('GET /users');
396
416
 
397
417
  // Invalidate with params
398
- await api.invalidateQueries('GET /users/:id', {
418
+ await api.invalidateQueries('GET /users/{id}', {
399
419
  params: { id: '123' }
400
420
  });
401
421
 
402
422
  // Invalidate multiple queries
403
423
  await Promise.all([
404
424
  api.invalidateQueries('GET /users'),
405
- api.invalidateQueries('GET /users/:id')
425
+ api.invalidateQueries('GET /users/{id}')
406
426
  ]);
407
427
  ```
408
428
 
@@ -411,20 +431,20 @@ await Promise.all([
411
431
  Implement optimistic UI updates:
412
432
 
413
433
  ```typescript
414
- const updateUser = api.useMutation('PUT /users/:id', {
434
+ const updateUser = api.useMutation('PUT /users/{id}', {
415
435
  onMutate: async (variables) => {
416
436
  // Cancel outgoing refetches
417
- await api.cancelQueries('GET /users/:id', {
437
+ await api.cancelQueries('GET /users/{id}', {
418
438
  params: { id: variables.params.id }
419
439
  });
420
440
 
421
441
  // Snapshot previous value
422
- const previousUser = api.getQueryData('GET /users/:id', {
442
+ const previousUser = api.getQueryData('GET /users/{id}', {
423
443
  params: { id: variables.params.id }
424
444
  });
425
445
 
426
446
  // Optimistically update
427
- api.setQueryData('GET /users/:id', {
447
+ api.setQueryData('GET /users/{id}', {
428
448
  params: { id: variables.params.id }
429
449
  }, variables.body);
430
450
 
@@ -433,14 +453,14 @@ const updateUser = api.useMutation('PUT /users/:id', {
433
453
  onError: (err, variables, context) => {
434
454
  // Rollback on error
435
455
  if (context?.previousUser) {
436
- api.setQueryData('GET /users/:id', {
456
+ api.setQueryData('GET /users/{id}', {
437
457
  params: { id: variables.params.id }
438
458
  }, context.previousUser);
439
459
  }
440
460
  },
441
461
  onSettled: (data, error, variables) => {
442
462
  // Refetch after mutation
443
- api.invalidateQueries('GET /users/:id', {
463
+ api.invalidateQueries('GET /users/{id}', {
444
464
  params: { id: variables.params.id }
445
465
  });
446
466
  }
@@ -461,7 +481,7 @@ const api = createTypedFetcher<API>({
461
481
  });
462
482
 
463
483
  // Per-request headers
464
- const user = await api('GET /users/:id', {
484
+ const user = await api('GET /users/{id}', {
465
485
  params: { id: '123' },
466
486
  headers: {
467
487
  'X-Request-ID': requestId
@@ -477,7 +497,7 @@ Handle errors with full type safety:
477
497
  import { HttpError } from '@geekmidas/errors';
478
498
 
479
499
  try {
480
- const user = await api('GET /users/:id', {
500
+ const user = await api('GET /users/{id}', {
481
501
  params: { id: '123' }
482
502
  });
483
503
  } catch (error) {
@@ -537,7 +557,7 @@ function UsersList() {
537
557
 
538
558
  const handleUserHover = (userId: string) => {
539
559
  // Prefetch user details on hover
540
- api.prefetchQuery('GET /users/:id', {
560
+ api.prefetchQuery('GET /users/{id}', {
541
561
  params: { id: userId }
542
562
  });
543
563
  };
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_methods = require("./methods.cjs");
2
3
  const require_fetcher = require("./fetcher.cjs");
3
4
  //#region src/auth-fetcher.ts
4
5
  /**
@@ -53,7 +54,8 @@ function createAuthAwareFetcher(options) {
53
54
  };
54
55
  return baseFetcher.request(endpoint, mergedConfig);
55
56
  };
56
- return fetcher;
57
+ const api = fetcher;
58
+ return Object.assign(api, require_methods.methodCalls(api));
57
59
  }
58
60
  /**
59
61
  * Resolves auth headers based on the strategy and scheme.
@@ -1 +1 @@
1
- {"version":3,"file":"auth-fetcher.cjs","names":["TypedFetcher"],"sources":["../src/auth-fetcher.ts"],"sourcesContent":["import { TypedFetcher } from './fetcher';\nimport type {\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tTypedApiFunction,\n\tTypedEndpoint,\n} from './types';\n\nexport type { FetcherOptions } from './types';\n\n/**\n * Security scheme object matching OpenAPI 3.1 specification.\n */\nexport interface SecuritySchemeObject {\n\ttype: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';\n\tdescription?: string;\n\tname?: string;\n\tin?: 'query' | 'header' | 'cookie';\n\tscheme?: string;\n\tbearerFormat?: string;\n\tflows?: Record<string, unknown>;\n\topenIdConnectUrl?: string;\n\t[key: string]: unknown;\n}\n\n/**\n * Extract all non-null security scheme IDs that are actually used in the API.\n * This gives us the union of scheme names that endpoints require.\n */\nexport type UsedSecuritySchemes<\n\tEndpointAuth extends Record<string, string | null>,\n> = NonNullable<EndpointAuth[keyof EndpointAuth]>;\n\n/**\n * Interface for token storage and retrieval.\n * Compatible with @geekmidas/auth TokenClient.\n */\nexport interface TokenProvider {\n\t/**\n\t * Get a valid access token, refreshing if necessary.\n\t */\n\tgetValidAccessToken(): Promise<string | null>;\n\n\t/**\n\t * Create Authorization headers from the current token.\n\t */\n\tcreateValidAuthHeaders(): Promise<Record<string, string>>;\n}\n\n/**\n * Interface for API key providers.\n */\nexport interface ApiKeyProvider {\n\t/**\n\t * Get the API key value.\n\t */\n\tgetApiKey(): Promise<string> | string;\n}\n\n/**\n * Interface for AWS SigV4 request signing.\n */\nexport interface AwsSigner {\n\t/**\n\t * Sign a request with AWS SigV4.\n\t * @param url - The request URL\n\t * @param init - The request init object\n\t * @returns Headers to add to the request\n\t */\n\tsign(url: string, init: RequestInit): Promise<Record<string, string>>;\n}\n\n/**\n * Auth strategy configuration for a specific security scheme type.\n */\nexport type AuthStrategy =\n\t| { type: 'bearer'; tokenProvider: TokenProvider }\n\t| { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }\n\t| { type: 'iam'; signer: AwsSigner }\n\t| { type: 'none' };\n\n/**\n * Options for creating an auth-aware fetcher.\n *\n * @template EndpointAuth - Map of endpoint strings to their auth scheme (or null for public)\n * @template SecuritySchemes - Available security scheme definitions\n */\nexport interface AuthFetcherOptions<\n\tEndpointAuth extends Record<string, string | null>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject>,\n> extends Omit<FetcherOptions, 'onRequest'> {\n\t/**\n\t * Runtime map of endpoints to their required auth scheme.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tendpointAuth: EndpointAuth;\n\n\t/**\n\t * Security scheme definitions.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tsecuritySchemes: SecuritySchemes;\n\n\t/**\n\t * Auth strategies for security schemes that are actually used.\n\t * Only schemes referenced in endpointAuth are required.\n\t *\n\t * @example\n\t * ```typescript\n\t * // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }\n\t * // Then authStrategies must include strategies for 'jwt' and 'iam'\n\t * authStrategies: {\n\t * jwt: { type: 'bearer', tokenProvider },\n\t * iam: { type: 'iam', signer: awsSigner },\n\t * }\n\t * ```\n\t */\n\tauthStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;\n\n\t/**\n\t * Optional request interceptor (runs after auth headers are added).\n\t */\n\tonRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;\n}\n\n/**\n * Creates an auth-aware fetcher that automatically applies the correct\n * authentication based on the endpoint being called.\n *\n * @example\n * ```typescript\n * import { endpointAuth, securitySchemes, paths } from './openapi';\n * import { TokenClient } from '@geekmidas/auth/client';\n *\n * const tokenClient = new TokenClient({ ... });\n *\n * const api = createAuthAwareFetcher<paths>({\n * baseURL: 'https://api.example.com',\n * endpointAuth,\n * securitySchemes,\n * authStrategies: {\n * bearer: { type: 'bearer', tokenProvider: tokenClient },\n * iam: { type: 'iam', signer: awsSigner },\n * },\n * });\n *\n * // Bearer auth automatically applied\n * const user = await api('GET /users/{id}', { params: { id: '123' } });\n *\n * // IAM SigV4 auth automatically applied\n * const tenant = await api('POST /tenants', { body: { name: 'Acme' } });\n * ```\n */\nexport function createAuthAwareFetcher<\n\tPaths,\n\tEndpointAuth extends Record<string, string | null> = Record<\n\t\tstring,\n\t\tstring | null\n\t>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject> = Record<\n\t\tstring,\n\t\tSecuritySchemeObject\n\t>,\n>(\n\toptions: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n\t\tbaseURL: string;\n\t},\n): TypedApiFunction<Paths> {\n\tconst {\n\t\tendpointAuth,\n\t\tsecuritySchemes,\n\t\tauthStrategies,\n\t\tonRequest: userOnRequest,\n\t\t...fetcherOptions\n\t} = options;\n\n\t// Create base fetcher with user's onRequest if provided\n\tconst baseFetcher = new TypedFetcher<Paths>({\n\t\t...fetcherOptions,\n\t\tonRequest: userOnRequest,\n\t});\n\n\tconst fetcher = async <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> => {\n\t\t// Look up auth requirement for this endpoint\n\t\tconst schemeName = endpointAuth[endpoint as keyof EndpointAuth] as\n\t\t\t| string\n\t\t\t| null;\n\n\t\tlet authHeaders: Record<string, string> = {};\n\n\t\tif (schemeName) {\n\t\t\tconst scheme = securitySchemes[schemeName as keyof SecuritySchemes];\n\t\t\t// Since authStrategies is now required to have all used schemes,\n\t\t\t// we can safely access it - TypeScript ensures the strategy exists\n\t\t\tconst strategy =\n\t\t\t\tauthStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];\n\n\t\t\tif (strategy && scheme) {\n\t\t\t\tauthHeaders = await resolveAuthHeaders(strategy, scheme);\n\t\t\t}\n\t\t}\n\n\t\t// Merge auth headers with config headers\n\t\tconst existingHeaders =\n\t\t\tconfig && 'headers' in config && config.headers\n\t\t\t\t? (config.headers as Record<string, string>)\n\t\t\t\t: {};\n\n\t\tconst mergedConfig = {\n\t\t\t...config,\n\t\t\theaders: {\n\t\t\t\t...authHeaders,\n\t\t\t\t...existingHeaders,\n\t\t\t},\n\t\t} as unknown as FilteredRequestConfig<Paths, T>;\n\n\t\treturn baseFetcher.request(endpoint, mergedConfig);\n\t};\n\n\treturn fetcher as TypedApiFunction<Paths>;\n}\n\n/**\n * Resolves auth headers based on the strategy and scheme.\n */\nasync function resolveAuthHeaders(\n\tstrategy: AuthStrategy,\n\tscheme: SecuritySchemeObject,\n): Promise<Record<string, string>> {\n\tswitch (strategy.type) {\n\t\tcase 'bearer': {\n\t\t\treturn strategy.tokenProvider.createValidAuthHeaders();\n\t\t}\n\n\t\tcase 'apiKey': {\n\t\t\tconst apiKey = await strategy.apiKeyProvider.getApiKey();\n\t\t\tconst headerName = strategy.headerName || scheme.name || 'X-API-Key';\n\n\t\t\tif (scheme.in === 'header' || !scheme.in) {\n\t\t\t\treturn { [headerName]: apiKey };\n\t\t\t}\n\t\t\t// Note: query and cookie API keys are handled differently\n\t\t\t// For now, we only support header-based API keys\n\t\t\treturn {};\n\t\t}\n\n\t\tcase 'iam': {\n\t\t\t// IAM signing requires the full URL and request config\n\t\t\t// This is a simplified version - full implementation would need\n\t\t\t// access to the complete request\n\t\t\t// For now, return empty - the actual signing should be done\n\t\t\t// in a custom onRequest interceptor if needed\n\t\t\treturn {};\n\t\t}\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\n/**\n * Type helper to extract the security scheme ID from an endpoint.\n */\nexport type GetEndpointAuth<\n\tEndpointAuth extends Record<string, string | null>,\n\tEndpoint extends keyof EndpointAuth,\n> = EndpointAuth[Endpoint];\n\n/**\n * Type helper to get all authenticated endpoints.\n */\nexport type AuthenticatedEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? never : K;\n}[keyof EndpointAuth];\n\n/**\n * Type helper to get all public endpoints.\n */\nexport type PublicEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;\n}[keyof EndpointAuth];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0JA,SAAgB,uBAWf,SAG0B;CAC1B,MAAM,EACL,cACA,iBACA,gBACA,WAAW,eACX,GAAG,mBACA;CAGJ,MAAM,cAAc,IAAIA,gBAAAA,aAAoB;EAC3C,GAAG;EACH,WAAW;CACZ,CAAC;CAED,MAAM,UAAU,OACf,UACA,WACgD;EAEhD,MAAM,aAAa,aAAa;EAIhC,IAAI,cAAsC,CAAC;EAE3C,IAAI,YAAY;GACf,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACL,eAAe;GAEhB,IAAI,YAAY,QACf,cAAc,MAAM,mBAAmB,UAAU,MAAM;EAEzD;EAGA,MAAM,kBACL,UAAU,aAAa,UAAU,OAAO,UACpC,OAAO,UACR,CAAC;EAEL,MAAM,eAAe;GACpB,GAAG;GACH,SAAS;IACR,GAAG;IACH,GAAG;GACJ;EACD;EAEA,OAAO,YAAY,QAAQ,UAAU,YAAY;CAClD;CAEA,OAAO;AACR;;;;AAKA,eAAe,mBACd,UACA,QACkC;CAClC,QAAQ,SAAS,MAAjB;EACC,KAAK,UACJ,OAAO,SAAS,cAAc,uBAAuB;EAGtD,KAAK,UAAU;GACd,MAAM,SAAS,MAAM,SAAS,eAAe,UAAU;GACvD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;GAEzD,IAAI,OAAO,OAAO,YAAY,CAAC,OAAO,IACrC,OAAO,GAAG,aAAa,OAAO;GAI/B,OAAO,CAAC;EACT;EAEA,KAAK,OAMJ,OAAO,CAAC;EAET,SACC,OAAO,CAAC;CACV;AACD"}
1
+ {"version":3,"file":"auth-fetcher.cjs","names":["TypedFetcher","methodCalls"],"sources":["../src/auth-fetcher.ts"],"sourcesContent":["import { TypedFetcher } from './fetcher';\nimport { methodCalls } from './methods';\nimport type {\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tTypedApiFunction,\n\tTypedEndpoint,\n} from './types';\n\nexport type { FetcherOptions } from './types';\n\n/**\n * Security scheme object matching OpenAPI 3.1 specification.\n */\nexport interface SecuritySchemeObject {\n\ttype: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';\n\tdescription?: string;\n\tname?: string;\n\tin?: 'query' | 'header' | 'cookie';\n\tscheme?: string;\n\tbearerFormat?: string;\n\tflows?: Record<string, unknown>;\n\topenIdConnectUrl?: string;\n\t[key: string]: unknown;\n}\n\n/**\n * Extract all non-null security scheme IDs that are actually used in the API.\n * This gives us the union of scheme names that endpoints require.\n */\nexport type UsedSecuritySchemes<\n\tEndpointAuth extends Record<string, string | null>,\n> = NonNullable<EndpointAuth[keyof EndpointAuth]>;\n\n/**\n * Interface for token storage and retrieval.\n * Compatible with @geekmidas/auth TokenClient.\n */\nexport interface TokenProvider {\n\t/**\n\t * Get a valid access token, refreshing if necessary.\n\t */\n\tgetValidAccessToken(): Promise<string | null>;\n\n\t/**\n\t * Create Authorization headers from the current token.\n\t */\n\tcreateValidAuthHeaders(): Promise<Record<string, string>>;\n}\n\n/**\n * Interface for API key providers.\n */\nexport interface ApiKeyProvider {\n\t/**\n\t * Get the API key value.\n\t */\n\tgetApiKey(): Promise<string> | string;\n}\n\n/**\n * Interface for AWS SigV4 request signing.\n */\nexport interface AwsSigner {\n\t/**\n\t * Sign a request with AWS SigV4.\n\t * @param url - The request URL\n\t * @param init - The request init object\n\t * @returns Headers to add to the request\n\t */\n\tsign(url: string, init: RequestInit): Promise<Record<string, string>>;\n}\n\n/**\n * Auth strategy configuration for a specific security scheme type.\n */\nexport type AuthStrategy =\n\t| { type: 'bearer'; tokenProvider: TokenProvider }\n\t| { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }\n\t| { type: 'iam'; signer: AwsSigner }\n\t| { type: 'none' };\n\n/**\n * Options for creating an auth-aware fetcher.\n *\n * @template EndpointAuth - Map of endpoint strings to their auth scheme (or null for public)\n * @template SecuritySchemes - Available security scheme definitions\n */\nexport interface AuthFetcherOptions<\n\tEndpointAuth extends Record<string, string | null>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject>,\n> extends Omit<FetcherOptions, 'onRequest'> {\n\t/**\n\t * Runtime map of endpoints to their required auth scheme.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tendpointAuth: EndpointAuth;\n\n\t/**\n\t * Security scheme definitions.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tsecuritySchemes: SecuritySchemes;\n\n\t/**\n\t * Auth strategies for security schemes that are actually used.\n\t * Only schemes referenced in endpointAuth are required.\n\t *\n\t * @example\n\t * ```typescript\n\t * // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }\n\t * // Then authStrategies must include strategies for 'jwt' and 'iam'\n\t * authStrategies: {\n\t * jwt: { type: 'bearer', tokenProvider },\n\t * iam: { type: 'iam', signer: awsSigner },\n\t * }\n\t * ```\n\t */\n\tauthStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;\n\n\t/**\n\t * Optional request interceptor (runs after auth headers are added).\n\t */\n\tonRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;\n}\n\n/**\n * Creates an auth-aware fetcher that automatically applies the correct\n * authentication based on the endpoint being called.\n *\n * @example\n * ```typescript\n * import { endpointAuth, securitySchemes, paths } from './openapi';\n * import { TokenClient } from '@geekmidas/auth/client';\n *\n * const tokenClient = new TokenClient({ ... });\n *\n * const api = createAuthAwareFetcher<paths>({\n * baseURL: 'https://api.example.com',\n * endpointAuth,\n * securitySchemes,\n * authStrategies: {\n * bearer: { type: 'bearer', tokenProvider: tokenClient },\n * iam: { type: 'iam', signer: awsSigner },\n * },\n * });\n *\n * // Bearer auth automatically applied\n * const user = await api('GET /users/{id}', { params: { id: '123' } });\n *\n * // IAM SigV4 auth automatically applied\n * const tenant = await api('POST /tenants', { body: { name: 'Acme' } });\n * ```\n */\nexport function createAuthAwareFetcher<\n\tPaths,\n\tEndpointAuth extends Record<string, string | null> = Record<\n\t\tstring,\n\t\tstring | null\n\t>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject> = Record<\n\t\tstring,\n\t\tSecuritySchemeObject\n\t>,\n>(\n\toptions: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n\t\tbaseURL: string;\n\t},\n): TypedApiFunction<Paths> {\n\tconst {\n\t\tendpointAuth,\n\t\tsecuritySchemes,\n\t\tauthStrategies,\n\t\tonRequest: userOnRequest,\n\t\t...fetcherOptions\n\t} = options;\n\n\t// Create base fetcher with user's onRequest if provided\n\tconst baseFetcher = new TypedFetcher<Paths>({\n\t\t...fetcherOptions,\n\t\tonRequest: userOnRequest,\n\t});\n\n\tconst fetcher = async <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> => {\n\t\t// Look up auth requirement for this endpoint\n\t\tconst schemeName = endpointAuth[endpoint as keyof EndpointAuth] as\n\t\t\t| string\n\t\t\t| null;\n\n\t\tlet authHeaders: Record<string, string> = {};\n\n\t\tif (schemeName) {\n\t\t\tconst scheme = securitySchemes[schemeName as keyof SecuritySchemes];\n\t\t\t// Since authStrategies is now required to have all used schemes,\n\t\t\t// we can safely access it - TypeScript ensures the strategy exists\n\t\t\tconst strategy =\n\t\t\t\tauthStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];\n\n\t\t\tif (strategy && scheme) {\n\t\t\t\tauthHeaders = await resolveAuthHeaders(strategy, scheme);\n\t\t\t}\n\t\t}\n\n\t\t// Merge auth headers with config headers\n\t\tconst existingHeaders =\n\t\t\tconfig && 'headers' in config && config.headers\n\t\t\t\t? (config.headers as Record<string, string>)\n\t\t\t\t: {};\n\n\t\tconst mergedConfig = {\n\t\t\t...config,\n\t\t\theaders: {\n\t\t\t\t...authHeaders,\n\t\t\t\t...existingHeaders,\n\t\t\t},\n\t\t} as unknown as FilteredRequestConfig<Paths, T>;\n\n\t\treturn baseFetcher.request(endpoint, mergedConfig);\n\t};\n\n\tconst api = fetcher as TypedApiFunction<Paths>;\n\treturn Object.assign(api, methodCalls<Paths>(api));\n}\n\n/**\n * Resolves auth headers based on the strategy and scheme.\n */\nasync function resolveAuthHeaders(\n\tstrategy: AuthStrategy,\n\tscheme: SecuritySchemeObject,\n): Promise<Record<string, string>> {\n\tswitch (strategy.type) {\n\t\tcase 'bearer': {\n\t\t\treturn strategy.tokenProvider.createValidAuthHeaders();\n\t\t}\n\n\t\tcase 'apiKey': {\n\t\t\tconst apiKey = await strategy.apiKeyProvider.getApiKey();\n\t\t\tconst headerName = strategy.headerName || scheme.name || 'X-API-Key';\n\n\t\t\tif (scheme.in === 'header' || !scheme.in) {\n\t\t\t\treturn { [headerName]: apiKey };\n\t\t\t}\n\t\t\t// Note: query and cookie API keys are handled differently\n\t\t\t// For now, we only support header-based API keys\n\t\t\treturn {};\n\t\t}\n\n\t\tcase 'iam': {\n\t\t\t// IAM signing requires the full URL and request config\n\t\t\t// This is a simplified version - full implementation would need\n\t\t\t// access to the complete request\n\t\t\t// For now, return empty - the actual signing should be done\n\t\t\t// in a custom onRequest interceptor if needed\n\t\t\treturn {};\n\t\t}\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\n/**\n * Type helper to extract the security scheme ID from an endpoint.\n */\nexport type GetEndpointAuth<\n\tEndpointAuth extends Record<string, string | null>,\n\tEndpoint extends keyof EndpointAuth,\n> = EndpointAuth[Endpoint];\n\n/**\n * Type helper to get all authenticated endpoints.\n */\nexport type AuthenticatedEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? never : K;\n}[keyof EndpointAuth];\n\n/**\n * Type helper to get all public endpoints.\n */\nexport type PublicEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;\n}[keyof EndpointAuth];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2JA,SAAgB,uBAWf,SAG0B;CAC1B,MAAM,EACL,cACA,iBACA,gBACA,WAAW,eACX,GAAG,mBACA;CAGJ,MAAM,cAAc,IAAIA,gBAAAA,aAAoB;EAC3C,GAAG;EACH,WAAW;CACZ,CAAC;CAED,MAAM,UAAU,OACf,UACA,WACgD;EAEhD,MAAM,aAAa,aAAa;EAIhC,IAAI,cAAsC,CAAC;EAE3C,IAAI,YAAY;GACf,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACL,eAAe;GAEhB,IAAI,YAAY,QACf,cAAc,MAAM,mBAAmB,UAAU,MAAM;EAEzD;EAGA,MAAM,kBACL,UAAU,aAAa,UAAU,OAAO,UACpC,OAAO,UACR,CAAC;EAEL,MAAM,eAAe;GACpB,GAAG;GACH,SAAS;IACR,GAAG;IACH,GAAG;GACJ;EACD;EAEA,OAAO,YAAY,QAAQ,UAAU,YAAY;CAClD;CAEA,MAAM,MAAM;CACZ,OAAO,OAAO,OAAO,KAAKC,gBAAAA,YAAmB,GAAG,CAAC;AAClD;;;;AAKA,eAAe,mBACd,UACA,QACkC;CAClC,QAAQ,SAAS,MAAjB;EACC,KAAK,UACJ,OAAO,SAAS,cAAc,uBAAuB;EAGtD,KAAK,UAAU;GACd,MAAM,SAAS,MAAM,SAAS,eAAe,UAAU;GACvD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;GAEzD,IAAI,OAAO,OAAO,YAAY,CAAC,OAAO,IACrC,OAAO,GAAG,aAAa,OAAO;GAI/B,OAAO,CAAC;EACT;EAEA,KAAK,OAMJ,OAAO,CAAC;EAET,SACC,OAAO,CAAC;CACV;AACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-fetcher.d.cts","names":[],"sources":["../src/auth-fetcher.ts"],"mappings":";;;;;iBAciB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;GACC;;;;;;YAOU,oBACX,qBAAqB,iCAClB,YAAY,mBAAmB;;;;;iBAMlB;;;;EAIhB,uBAAuB;;;;EAKvB,0BAA0B,QAAQ;;;;;iBAMlB;;;;EAIhB,aAAa;;;;;iBAMG;;;;;;;EAOhB,KAAK,aAAa,MAAM,cAAc,QAAQ;;;;;YAMnC;EACP;EAAgB,eAAe;;EAC/B;EAAgB,gBAAgB;EAAgB;;EAChD;EAAa,QAAQ;;EACrB;;;;;;;;iBAQY,mBAChB,qBAAqB,+BACrB,wBAAwB,eAAe,+BAC9B,KAAK;;;;;EAKd,cAAc;;;;;EAMd,iBAAiB;;;;;;;;;;;;;;;EAgBjB,gBAAgB,OAAO,oBAAoB,eAAe;;;;EAK1D,aAAa,QAAQ,gBAAgB,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+B5C,uBACf,OACA,qBAAqB,gCAAgC,+BAIrD,wBAAwB,eAAe,wBAAwB,eAE9D,uBAGD,SAAS,mBAAmB,cAAc;EACzC;IAEC,iBAAiB;;;;YAkGR,gBACX,qBAAqB,+BACrB,uBAAuB,gBACpB,aAAa;;;;YAKL,uBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,0BAA0B,WAC3D;;;;YAKI,gBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,kBAAkB,mBACnD"}
1
+ {"version":3,"file":"auth-fetcher.d.cts","names":[],"sources":["../src/auth-fetcher.ts"],"mappings":";;;;;iBAeiB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;GACC;;;;;;YAOU,oBACX,qBAAqB,iCAClB,YAAY,mBAAmB;;;;;iBAMlB;;;;EAIhB,uBAAuB;;;;EAKvB,0BAA0B,QAAQ;;;;;iBAMlB;;;;EAIhB,aAAa;;;;;iBAMG;;;;;;;EAOhB,KAAK,aAAa,MAAM,cAAc,QAAQ;;;;;YAMnC;EACP;EAAgB,eAAe;;EAC/B;EAAgB,gBAAgB;EAAgB;;EAChD;EAAa,QAAQ;;EACrB;;;;;;;;iBAQY,mBAChB,qBAAqB,+BACrB,wBAAwB,eAAe,+BAC9B,KAAK;;;;;EAKd,cAAc;;;;;EAMd,iBAAiB;;;;;;;;;;;;;;;EAgBjB,gBAAgB,OAAO,oBAAoB,eAAe;;;;EAK1D,aAAa,QAAQ,gBAAgB,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+B5C,uBACf,OACA,qBAAqB,gCAAgC,+BAIrD,wBAAwB,eAAe,wBAAwB,eAE9D,uBAGD,SAAS,mBAAmB,cAAc;EACzC;IAEC,iBAAiB;;;;YAmGR,gBACX,qBAAqB,+BACrB,uBAAuB,gBACpB,aAAa;;;;YAKL,uBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,0BAA0B,WAC3D;;;;YAKI,gBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,kBAAkB,mBACnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth-fetcher.d.mts","names":[],"sources":["../src/auth-fetcher.ts"],"mappings":";;;;;iBAciB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;GACC;;;;;;YAOU,oBACX,qBAAqB,iCAClB,YAAY,mBAAmB;;;;;iBAMlB;;;;EAIhB,uBAAuB;;;;EAKvB,0BAA0B,QAAQ;;;;;iBAMlB;;;;EAIhB,aAAa;;;;;iBAMG;;;;;;;EAOhB,KAAK,aAAa,MAAM,cAAc,QAAQ;;;;;YAMnC;EACP;EAAgB,eAAe;;EAC/B;EAAgB,gBAAgB;EAAgB;;EAChD;EAAa,QAAQ;;EACrB;;;;;;;;iBAQY,mBAChB,qBAAqB,+BACrB,wBAAwB,eAAe,+BAC9B,KAAK;;;;;EAKd,cAAc;;;;;EAMd,iBAAiB;;;;;;;;;;;;;;;EAgBjB,gBAAgB,OAAO,oBAAoB,eAAe;;;;EAK1D,aAAa,QAAQ,gBAAgB,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+B5C,uBACf,OACA,qBAAqB,gCAAgC,+BAIrD,wBAAwB,eAAe,wBAAwB,eAE9D,uBAGD,SAAS,mBAAmB,cAAc;EACzC;IAEC,iBAAiB;;;;YAkGR,gBACX,qBAAqB,+BACrB,uBAAuB,gBACpB,aAAa;;;;YAKL,uBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,0BAA0B,WAC3D;;;;YAKI,gBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,kBAAkB,mBACnD"}
1
+ {"version":3,"file":"auth-fetcher.d.mts","names":[],"sources":["../src/auth-fetcher.ts"],"mappings":";;;;;iBAeiB;EAChB;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;GACC;;;;;;YAOU,oBACX,qBAAqB,iCAClB,YAAY,mBAAmB;;;;;iBAMlB;;;;EAIhB,uBAAuB;;;;EAKvB,0BAA0B,QAAQ;;;;;iBAMlB;;;;EAIhB,aAAa;;;;;iBAMG;;;;;;;EAOhB,KAAK,aAAa,MAAM,cAAc,QAAQ;;;;;YAMnC;EACP;EAAgB,eAAe;;EAC/B;EAAgB,gBAAgB;EAAgB;;EAChD;EAAa,QAAQ;;EACrB;;;;;;;;iBAQY,mBAChB,qBAAqB,+BACrB,wBAAwB,eAAe,+BAC9B,KAAK;;;;;EAKd,cAAc;;;;;EAMd,iBAAiB;;;;;;;;;;;;;;;EAgBjB,gBAAgB,OAAO,oBAAoB,eAAe;;;;EAK1D,aAAa,QAAQ,gBAAgB,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA+B5C,uBACf,OACA,qBAAqB,gCAAgC,+BAIrD,wBAAwB,eAAe,wBAAwB,eAE9D,uBAGD,SAAS,mBAAmB,cAAc;EACzC;IAEC,iBAAiB;;;;YAmGR,gBACX,qBAAqB,+BACrB,uBAAuB,gBACpB,aAAa;;;;YAKL,uBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,0BAA0B,WAC3D;;;;YAKI,gBACX,qBAAqB,oCAEpB,WAAW,eAAe,aAAa,kBAAkB,mBACnD"}
@@ -1,3 +1,4 @@
1
+ import { methodCalls } from "./methods.mjs";
1
2
  import { TypedFetcher } from "./fetcher.mjs";
2
3
  //#region src/auth-fetcher.ts
3
4
  /**
@@ -52,7 +53,8 @@ function createAuthAwareFetcher(options) {
52
53
  };
53
54
  return baseFetcher.request(endpoint, mergedConfig);
54
55
  };
55
- return fetcher;
56
+ const api = fetcher;
57
+ return Object.assign(api, methodCalls(api));
56
58
  }
57
59
  /**
58
60
  * Resolves auth headers based on the strategy and scheme.
@@ -1 +1 @@
1
- {"version":3,"file":"auth-fetcher.mjs","names":[],"sources":["../src/auth-fetcher.ts"],"sourcesContent":["import { TypedFetcher } from './fetcher';\nimport type {\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tTypedApiFunction,\n\tTypedEndpoint,\n} from './types';\n\nexport type { FetcherOptions } from './types';\n\n/**\n * Security scheme object matching OpenAPI 3.1 specification.\n */\nexport interface SecuritySchemeObject {\n\ttype: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';\n\tdescription?: string;\n\tname?: string;\n\tin?: 'query' | 'header' | 'cookie';\n\tscheme?: string;\n\tbearerFormat?: string;\n\tflows?: Record<string, unknown>;\n\topenIdConnectUrl?: string;\n\t[key: string]: unknown;\n}\n\n/**\n * Extract all non-null security scheme IDs that are actually used in the API.\n * This gives us the union of scheme names that endpoints require.\n */\nexport type UsedSecuritySchemes<\n\tEndpointAuth extends Record<string, string | null>,\n> = NonNullable<EndpointAuth[keyof EndpointAuth]>;\n\n/**\n * Interface for token storage and retrieval.\n * Compatible with @geekmidas/auth TokenClient.\n */\nexport interface TokenProvider {\n\t/**\n\t * Get a valid access token, refreshing if necessary.\n\t */\n\tgetValidAccessToken(): Promise<string | null>;\n\n\t/**\n\t * Create Authorization headers from the current token.\n\t */\n\tcreateValidAuthHeaders(): Promise<Record<string, string>>;\n}\n\n/**\n * Interface for API key providers.\n */\nexport interface ApiKeyProvider {\n\t/**\n\t * Get the API key value.\n\t */\n\tgetApiKey(): Promise<string> | string;\n}\n\n/**\n * Interface for AWS SigV4 request signing.\n */\nexport interface AwsSigner {\n\t/**\n\t * Sign a request with AWS SigV4.\n\t * @param url - The request URL\n\t * @param init - The request init object\n\t * @returns Headers to add to the request\n\t */\n\tsign(url: string, init: RequestInit): Promise<Record<string, string>>;\n}\n\n/**\n * Auth strategy configuration for a specific security scheme type.\n */\nexport type AuthStrategy =\n\t| { type: 'bearer'; tokenProvider: TokenProvider }\n\t| { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }\n\t| { type: 'iam'; signer: AwsSigner }\n\t| { type: 'none' };\n\n/**\n * Options for creating an auth-aware fetcher.\n *\n * @template EndpointAuth - Map of endpoint strings to their auth scheme (or null for public)\n * @template SecuritySchemes - Available security scheme definitions\n */\nexport interface AuthFetcherOptions<\n\tEndpointAuth extends Record<string, string | null>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject>,\n> extends Omit<FetcherOptions, 'onRequest'> {\n\t/**\n\t * Runtime map of endpoints to their required auth scheme.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tendpointAuth: EndpointAuth;\n\n\t/**\n\t * Security scheme definitions.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tsecuritySchemes: SecuritySchemes;\n\n\t/**\n\t * Auth strategies for security schemes that are actually used.\n\t * Only schemes referenced in endpointAuth are required.\n\t *\n\t * @example\n\t * ```typescript\n\t * // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }\n\t * // Then authStrategies must include strategies for 'jwt' and 'iam'\n\t * authStrategies: {\n\t * jwt: { type: 'bearer', tokenProvider },\n\t * iam: { type: 'iam', signer: awsSigner },\n\t * }\n\t * ```\n\t */\n\tauthStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;\n\n\t/**\n\t * Optional request interceptor (runs after auth headers are added).\n\t */\n\tonRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;\n}\n\n/**\n * Creates an auth-aware fetcher that automatically applies the correct\n * authentication based on the endpoint being called.\n *\n * @example\n * ```typescript\n * import { endpointAuth, securitySchemes, paths } from './openapi';\n * import { TokenClient } from '@geekmidas/auth/client';\n *\n * const tokenClient = new TokenClient({ ... });\n *\n * const api = createAuthAwareFetcher<paths>({\n * baseURL: 'https://api.example.com',\n * endpointAuth,\n * securitySchemes,\n * authStrategies: {\n * bearer: { type: 'bearer', tokenProvider: tokenClient },\n * iam: { type: 'iam', signer: awsSigner },\n * },\n * });\n *\n * // Bearer auth automatically applied\n * const user = await api('GET /users/{id}', { params: { id: '123' } });\n *\n * // IAM SigV4 auth automatically applied\n * const tenant = await api('POST /tenants', { body: { name: 'Acme' } });\n * ```\n */\nexport function createAuthAwareFetcher<\n\tPaths,\n\tEndpointAuth extends Record<string, string | null> = Record<\n\t\tstring,\n\t\tstring | null\n\t>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject> = Record<\n\t\tstring,\n\t\tSecuritySchemeObject\n\t>,\n>(\n\toptions: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n\t\tbaseURL: string;\n\t},\n): TypedApiFunction<Paths> {\n\tconst {\n\t\tendpointAuth,\n\t\tsecuritySchemes,\n\t\tauthStrategies,\n\t\tonRequest: userOnRequest,\n\t\t...fetcherOptions\n\t} = options;\n\n\t// Create base fetcher with user's onRequest if provided\n\tconst baseFetcher = new TypedFetcher<Paths>({\n\t\t...fetcherOptions,\n\t\tonRequest: userOnRequest,\n\t});\n\n\tconst fetcher = async <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> => {\n\t\t// Look up auth requirement for this endpoint\n\t\tconst schemeName = endpointAuth[endpoint as keyof EndpointAuth] as\n\t\t\t| string\n\t\t\t| null;\n\n\t\tlet authHeaders: Record<string, string> = {};\n\n\t\tif (schemeName) {\n\t\t\tconst scheme = securitySchemes[schemeName as keyof SecuritySchemes];\n\t\t\t// Since authStrategies is now required to have all used schemes,\n\t\t\t// we can safely access it - TypeScript ensures the strategy exists\n\t\t\tconst strategy =\n\t\t\t\tauthStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];\n\n\t\t\tif (strategy && scheme) {\n\t\t\t\tauthHeaders = await resolveAuthHeaders(strategy, scheme);\n\t\t\t}\n\t\t}\n\n\t\t// Merge auth headers with config headers\n\t\tconst existingHeaders =\n\t\t\tconfig && 'headers' in config && config.headers\n\t\t\t\t? (config.headers as Record<string, string>)\n\t\t\t\t: {};\n\n\t\tconst mergedConfig = {\n\t\t\t...config,\n\t\t\theaders: {\n\t\t\t\t...authHeaders,\n\t\t\t\t...existingHeaders,\n\t\t\t},\n\t\t} as unknown as FilteredRequestConfig<Paths, T>;\n\n\t\treturn baseFetcher.request(endpoint, mergedConfig);\n\t};\n\n\treturn fetcher as TypedApiFunction<Paths>;\n}\n\n/**\n * Resolves auth headers based on the strategy and scheme.\n */\nasync function resolveAuthHeaders(\n\tstrategy: AuthStrategy,\n\tscheme: SecuritySchemeObject,\n): Promise<Record<string, string>> {\n\tswitch (strategy.type) {\n\t\tcase 'bearer': {\n\t\t\treturn strategy.tokenProvider.createValidAuthHeaders();\n\t\t}\n\n\t\tcase 'apiKey': {\n\t\t\tconst apiKey = await strategy.apiKeyProvider.getApiKey();\n\t\t\tconst headerName = strategy.headerName || scheme.name || 'X-API-Key';\n\n\t\t\tif (scheme.in === 'header' || !scheme.in) {\n\t\t\t\treturn { [headerName]: apiKey };\n\t\t\t}\n\t\t\t// Note: query and cookie API keys are handled differently\n\t\t\t// For now, we only support header-based API keys\n\t\t\treturn {};\n\t\t}\n\n\t\tcase 'iam': {\n\t\t\t// IAM signing requires the full URL and request config\n\t\t\t// This is a simplified version - full implementation would need\n\t\t\t// access to the complete request\n\t\t\t// For now, return empty - the actual signing should be done\n\t\t\t// in a custom onRequest interceptor if needed\n\t\t\treturn {};\n\t\t}\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\n/**\n * Type helper to extract the security scheme ID from an endpoint.\n */\nexport type GetEndpointAuth<\n\tEndpointAuth extends Record<string, string | null>,\n\tEndpoint extends keyof EndpointAuth,\n> = EndpointAuth[Endpoint];\n\n/**\n * Type helper to get all authenticated endpoints.\n */\nexport type AuthenticatedEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? never : K;\n}[keyof EndpointAuth];\n\n/**\n * Type helper to get all public endpoints.\n */\nexport type PublicEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;\n}[keyof EndpointAuth];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0JA,SAAgB,uBAWf,SAG0B;CAC1B,MAAM,EACL,cACA,iBACA,gBACA,WAAW,eACX,GAAG,mBACA;CAGJ,MAAM,cAAc,IAAI,aAAoB;EAC3C,GAAG;EACH,WAAW;CACZ,CAAC;CAED,MAAM,UAAU,OACf,UACA,WACgD;EAEhD,MAAM,aAAa,aAAa;EAIhC,IAAI,cAAsC,CAAC;EAE3C,IAAI,YAAY;GACf,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACL,eAAe;GAEhB,IAAI,YAAY,QACf,cAAc,MAAM,mBAAmB,UAAU,MAAM;EAEzD;EAGA,MAAM,kBACL,UAAU,aAAa,UAAU,OAAO,UACpC,OAAO,UACR,CAAC;EAEL,MAAM,eAAe;GACpB,GAAG;GACH,SAAS;IACR,GAAG;IACH,GAAG;GACJ;EACD;EAEA,OAAO,YAAY,QAAQ,UAAU,YAAY;CAClD;CAEA,OAAO;AACR;;;;AAKA,eAAe,mBACd,UACA,QACkC;CAClC,QAAQ,SAAS,MAAjB;EACC,KAAK,UACJ,OAAO,SAAS,cAAc,uBAAuB;EAGtD,KAAK,UAAU;GACd,MAAM,SAAS,MAAM,SAAS,eAAe,UAAU;GACvD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;GAEzD,IAAI,OAAO,OAAO,YAAY,CAAC,OAAO,IACrC,OAAO,GAAG,aAAa,OAAO;GAI/B,OAAO,CAAC;EACT;EAEA,KAAK,OAMJ,OAAO,CAAC;EAET,SACC,OAAO,CAAC;CACV;AACD"}
1
+ {"version":3,"file":"auth-fetcher.mjs","names":[],"sources":["../src/auth-fetcher.ts"],"sourcesContent":["import { TypedFetcher } from './fetcher';\nimport { methodCalls } from './methods';\nimport type {\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tTypedApiFunction,\n\tTypedEndpoint,\n} from './types';\n\nexport type { FetcherOptions } from './types';\n\n/**\n * Security scheme object matching OpenAPI 3.1 specification.\n */\nexport interface SecuritySchemeObject {\n\ttype: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';\n\tdescription?: string;\n\tname?: string;\n\tin?: 'query' | 'header' | 'cookie';\n\tscheme?: string;\n\tbearerFormat?: string;\n\tflows?: Record<string, unknown>;\n\topenIdConnectUrl?: string;\n\t[key: string]: unknown;\n}\n\n/**\n * Extract all non-null security scheme IDs that are actually used in the API.\n * This gives us the union of scheme names that endpoints require.\n */\nexport type UsedSecuritySchemes<\n\tEndpointAuth extends Record<string, string | null>,\n> = NonNullable<EndpointAuth[keyof EndpointAuth]>;\n\n/**\n * Interface for token storage and retrieval.\n * Compatible with @geekmidas/auth TokenClient.\n */\nexport interface TokenProvider {\n\t/**\n\t * Get a valid access token, refreshing if necessary.\n\t */\n\tgetValidAccessToken(): Promise<string | null>;\n\n\t/**\n\t * Create Authorization headers from the current token.\n\t */\n\tcreateValidAuthHeaders(): Promise<Record<string, string>>;\n}\n\n/**\n * Interface for API key providers.\n */\nexport interface ApiKeyProvider {\n\t/**\n\t * Get the API key value.\n\t */\n\tgetApiKey(): Promise<string> | string;\n}\n\n/**\n * Interface for AWS SigV4 request signing.\n */\nexport interface AwsSigner {\n\t/**\n\t * Sign a request with AWS SigV4.\n\t * @param url - The request URL\n\t * @param init - The request init object\n\t * @returns Headers to add to the request\n\t */\n\tsign(url: string, init: RequestInit): Promise<Record<string, string>>;\n}\n\n/**\n * Auth strategy configuration for a specific security scheme type.\n */\nexport type AuthStrategy =\n\t| { type: 'bearer'; tokenProvider: TokenProvider }\n\t| { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }\n\t| { type: 'iam'; signer: AwsSigner }\n\t| { type: 'none' };\n\n/**\n * Options for creating an auth-aware fetcher.\n *\n * @template EndpointAuth - Map of endpoint strings to their auth scheme (or null for public)\n * @template SecuritySchemes - Available security scheme definitions\n */\nexport interface AuthFetcherOptions<\n\tEndpointAuth extends Record<string, string | null>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject>,\n> extends Omit<FetcherOptions, 'onRequest'> {\n\t/**\n\t * Runtime map of endpoints to their required auth scheme.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tendpointAuth: EndpointAuth;\n\n\t/**\n\t * Security scheme definitions.\n\t * Generated by `gkm openapi --ts`.\n\t */\n\tsecuritySchemes: SecuritySchemes;\n\n\t/**\n\t * Auth strategies for security schemes that are actually used.\n\t * Only schemes referenced in endpointAuth are required.\n\t *\n\t * @example\n\t * ```typescript\n\t * // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }\n\t * // Then authStrategies must include strategies for 'jwt' and 'iam'\n\t * authStrategies: {\n\t * jwt: { type: 'bearer', tokenProvider },\n\t * iam: { type: 'iam', signer: awsSigner },\n\t * }\n\t * ```\n\t */\n\tauthStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;\n\n\t/**\n\t * Optional request interceptor (runs after auth headers are added).\n\t */\n\tonRequest?: (config: RequestInit) => RequestInit | Promise<RequestInit>;\n}\n\n/**\n * Creates an auth-aware fetcher that automatically applies the correct\n * authentication based on the endpoint being called.\n *\n * @example\n * ```typescript\n * import { endpointAuth, securitySchemes, paths } from './openapi';\n * import { TokenClient } from '@geekmidas/auth/client';\n *\n * const tokenClient = new TokenClient({ ... });\n *\n * const api = createAuthAwareFetcher<paths>({\n * baseURL: 'https://api.example.com',\n * endpointAuth,\n * securitySchemes,\n * authStrategies: {\n * bearer: { type: 'bearer', tokenProvider: tokenClient },\n * iam: { type: 'iam', signer: awsSigner },\n * },\n * });\n *\n * // Bearer auth automatically applied\n * const user = await api('GET /users/{id}', { params: { id: '123' } });\n *\n * // IAM SigV4 auth automatically applied\n * const tenant = await api('POST /tenants', { body: { name: 'Acme' } });\n * ```\n */\nexport function createAuthAwareFetcher<\n\tPaths,\n\tEndpointAuth extends Record<string, string | null> = Record<\n\t\tstring,\n\t\tstring | null\n\t>,\n\tSecuritySchemes extends Record<string, SecuritySchemeObject> = Record<\n\t\tstring,\n\t\tSecuritySchemeObject\n\t>,\n>(\n\toptions: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n\t\tbaseURL: string;\n\t},\n): TypedApiFunction<Paths> {\n\tconst {\n\t\tendpointAuth,\n\t\tsecuritySchemes,\n\t\tauthStrategies,\n\t\tonRequest: userOnRequest,\n\t\t...fetcherOptions\n\t} = options;\n\n\t// Create base fetcher with user's onRequest if provided\n\tconst baseFetcher = new TypedFetcher<Paths>({\n\t\t...fetcherOptions,\n\t\tonRequest: userOnRequest,\n\t});\n\n\tconst fetcher = async <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> => {\n\t\t// Look up auth requirement for this endpoint\n\t\tconst schemeName = endpointAuth[endpoint as keyof EndpointAuth] as\n\t\t\t| string\n\t\t\t| null;\n\n\t\tlet authHeaders: Record<string, string> = {};\n\n\t\tif (schemeName) {\n\t\t\tconst scheme = securitySchemes[schemeName as keyof SecuritySchemes];\n\t\t\t// Since authStrategies is now required to have all used schemes,\n\t\t\t// we can safely access it - TypeScript ensures the strategy exists\n\t\t\tconst strategy =\n\t\t\t\tauthStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];\n\n\t\t\tif (strategy && scheme) {\n\t\t\t\tauthHeaders = await resolveAuthHeaders(strategy, scheme);\n\t\t\t}\n\t\t}\n\n\t\t// Merge auth headers with config headers\n\t\tconst existingHeaders =\n\t\t\tconfig && 'headers' in config && config.headers\n\t\t\t\t? (config.headers as Record<string, string>)\n\t\t\t\t: {};\n\n\t\tconst mergedConfig = {\n\t\t\t...config,\n\t\t\theaders: {\n\t\t\t\t...authHeaders,\n\t\t\t\t...existingHeaders,\n\t\t\t},\n\t\t} as unknown as FilteredRequestConfig<Paths, T>;\n\n\t\treturn baseFetcher.request(endpoint, mergedConfig);\n\t};\n\n\tconst api = fetcher as TypedApiFunction<Paths>;\n\treturn Object.assign(api, methodCalls<Paths>(api));\n}\n\n/**\n * Resolves auth headers based on the strategy and scheme.\n */\nasync function resolveAuthHeaders(\n\tstrategy: AuthStrategy,\n\tscheme: SecuritySchemeObject,\n): Promise<Record<string, string>> {\n\tswitch (strategy.type) {\n\t\tcase 'bearer': {\n\t\t\treturn strategy.tokenProvider.createValidAuthHeaders();\n\t\t}\n\n\t\tcase 'apiKey': {\n\t\t\tconst apiKey = await strategy.apiKeyProvider.getApiKey();\n\t\t\tconst headerName = strategy.headerName || scheme.name || 'X-API-Key';\n\n\t\t\tif (scheme.in === 'header' || !scheme.in) {\n\t\t\t\treturn { [headerName]: apiKey };\n\t\t\t}\n\t\t\t// Note: query and cookie API keys are handled differently\n\t\t\t// For now, we only support header-based API keys\n\t\t\treturn {};\n\t\t}\n\n\t\tcase 'iam': {\n\t\t\t// IAM signing requires the full URL and request config\n\t\t\t// This is a simplified version - full implementation would need\n\t\t\t// access to the complete request\n\t\t\t// For now, return empty - the actual signing should be done\n\t\t\t// in a custom onRequest interceptor if needed\n\t\t\treturn {};\n\t\t}\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\n/**\n * Type helper to extract the security scheme ID from an endpoint.\n */\nexport type GetEndpointAuth<\n\tEndpointAuth extends Record<string, string | null>,\n\tEndpoint extends keyof EndpointAuth,\n> = EndpointAuth[Endpoint];\n\n/**\n * Type helper to get all authenticated endpoints.\n */\nexport type AuthenticatedEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? never : K;\n}[keyof EndpointAuth];\n\n/**\n * Type helper to get all public endpoints.\n */\nexport type PublicEndpoints<\n\tEndpointAuth extends Record<string, string | null>,\n> = {\n\t[K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;\n}[keyof EndpointAuth];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2JA,SAAgB,uBAWf,SAG0B;CAC1B,MAAM,EACL,cACA,iBACA,gBACA,WAAW,eACX,GAAG,mBACA;CAGJ,MAAM,cAAc,IAAI,aAAoB;EAC3C,GAAG;EACH,WAAW;CACZ,CAAC;CAED,MAAM,UAAU,OACf,UACA,WACgD;EAEhD,MAAM,aAAa,aAAa;EAIhC,IAAI,cAAsC,CAAC;EAE3C,IAAI,YAAY;GACf,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACL,eAAe;GAEhB,IAAI,YAAY,QACf,cAAc,MAAM,mBAAmB,UAAU,MAAM;EAEzD;EAGA,MAAM,kBACL,UAAU,aAAa,UAAU,OAAO,UACpC,OAAO,UACR,CAAC;EAEL,MAAM,eAAe;GACpB,GAAG;GACH,SAAS;IACR,GAAG;IACH,GAAG;GACJ;EACD;EAEA,OAAO,YAAY,QAAQ,UAAU,YAAY;CAClD;CAEA,MAAM,MAAM;CACZ,OAAO,OAAO,OAAO,KAAK,YAAmB,GAAG,CAAC;AAClD;;;;AAKA,eAAe,mBACd,UACA,QACkC;CAClC,QAAQ,SAAS,MAAjB;EACC,KAAK,UACJ,OAAO,SAAS,cAAc,uBAAuB;EAGtD,KAAK,UAAU;GACd,MAAM,SAAS,MAAM,SAAS,eAAe,UAAU;GACvD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;GAEzD,IAAI,OAAO,OAAO,YAAY,CAAC,OAAO,IACrC,OAAO,GAAG,aAAa,OAAO;GAI/B,OAAO,CAAC;EACT;EAEA,KAAK,OAMJ,OAAO,CAAC;EAET,SACC,OAAO,CAAC;CACV;AACD"}
package/dist/fetcher.cjs CHANGED
@@ -21,6 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
+ const require_methods = require("./methods.cjs");
24
25
  let qs = require("qs");
25
26
  qs = __toESM(qs, 1);
26
27
  //#region src/fetcher.ts
@@ -102,7 +103,7 @@ var TypedFetcher = class TypedFetcher {
102
103
  function createTypedFetcher(options) {
103
104
  const fetcher = new TypedFetcher(options);
104
105
  const fn = (endpoint, config) => fetcher.request(endpoint, config);
105
- return Object.assign(fn, { wrap: (onError) => Object.assign(fetcher.wrap(onError), fn, { wrap: void 0 }) });
106
+ return Object.assign(fn, require_methods.methodCalls(fn), { wrap: (onError) => Object.assign(fetcher.wrap(onError), fn, { wrap: void 0 }) });
106
107
  }
107
108
  //#endregion
108
109
  exports.TypedFetcher = TypedFetcher;
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.cjs","names":[],"sources":["../src/fetcher.ts"],"sourcesContent":["import qs from 'qs';\nimport type {\n\tEndpointString,\n\tErrorTransformer,\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tParseEndpoint,\n\tTypedEndpoint,\n\tWrappedResult,\n} from './types';\n\nexport type { FetcherOptions, WrappedResult } from './types';\n\nexport class TypedFetcher<Paths> {\n\tprivate baseURL: string;\n\tprivate defaultHeaders: Record<string, string>;\n\tprivate options: FetcherOptions;\n\tprivate fetchFn: FetchFn;\n\n\tstatic getFetchFn(fn?: FetchFn): FetchFn {\n\t\tif (fn) {\n\t\t\treturn fn;\n\t\t}\n\n\t\tif (typeof window !== 'undefined' && typeof window.fetch === 'function') {\n\t\t\treturn window.fetch.bind(window);\n\t\t}\n\n\t\tif (\n\t\t\ttypeof globalThis !== 'undefined' &&\n\t\t\ttypeof globalThis.fetch === 'function'\n\t\t) {\n\t\t\treturn globalThis.fetch.bind(globalThis);\n\t\t}\n\n\t\tthrow new Error('No fetch implementation found');\n\t}\n\n\tconstructor(options: FetcherOptions = {}) {\n\t\tthis.baseURL = options.baseURL || '';\n\t\tthis.defaultHeaders = options.headers || {};\n\t\tthis.options = options;\n\t\tthis.fetchFn = TypedFetcher.getFetchFn(options.fetch);\n\t}\n\n\tasync request<T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> {\n\t\tconst { method, route } = this.parseEndpoint(endpoint);\n\n\t\t// Replace path parameters\n\t\tlet url = route;\n\t\tif (config && 'params' in config && config.params) {\n\t\t\tObject.entries(config.params as Record<string, unknown>).forEach(\n\t\t\t\t([key, value]) => {\n\t\t\t\t\turl = url.replace(`{${key}}`, encodeURIComponent(String(value)));\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Add query parameters\n\t\tif (config && 'query' in config && config.query) {\n\t\t\tconst queryString = qs.stringify(config.query, {\n\t\t\t\tencode: true,\n\t\t\t\tarrayFormat: 'brackets',\n\t\t\t\tskipNulls: true,\n\t\t\t});\n\t\t\tif (queryString) {\n\t\t\t\turl += `?${queryString}`;\n\t\t\t}\n\t\t}\n\n\t\t// Build request configuration\n\t\tlet requestConfig: RequestInit = {\n\t\t\tmethod: method.toUpperCase(),\n\t\t\theaders: {\n\t\t\t\t...this.defaultHeaders,\n\t\t\t\t...((config && 'headers' in config && config.headers) || {}),\n\t\t\t},\n\t\t};\n\n\t\t// Add body if present\n\t\tif (config && 'body' in config && config.body) {\n\t\t\trequestConfig.body = JSON.stringify(config.body);\n\t\t\trequestConfig.headers = {\n\t\t\t\t...requestConfig.headers,\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t};\n\t\t}\n\n\t\t// Apply request interceptor\n\t\tif (this.options.onRequest) {\n\t\t\trequestConfig = await this.options.onRequest(requestConfig);\n\t\t}\n\n\t\ttry {\n\t\t\t// Make the request\n\t\t\tlet response = await this.fetchFn(`${this.baseURL}${url}`, requestConfig);\n\n\t\t\t// Apply response interceptor\n\t\t\tif (this.options.onResponse) {\n\t\t\t\tresponse = await this.options.onResponse(response);\n\t\t\t}\n\n\t\t\t// Handle errors\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow response;\n\t\t\t}\n\n\t\t\t// Handle empty responses (204 No Content, etc.)\n\t\t\tif (\n\t\t\t\tresponse.status === 204 ||\n\t\t\t\tresponse.headers.get('content-length') === '0'\n\t\t\t) {\n\t\t\t\treturn undefined as ExtractEndpointResponse<Paths, T>;\n\t\t\t}\n\n\t\t\t// Parse JSON response\n\t\t\tconst data = await response.json();\n\t\t\treturn data as ExtractEndpointResponse<Paths, T>;\n\t\t} catch (error) {\n\t\t\t// Apply error handler\n\t\t\tif (this.options.onError) {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tawait this.options.onError(error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\twrap<E = unknown>(onError?: ErrorTransformer<E>) {\n\t\treturn <T extends TypedEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t\t): Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>> =>\n\t\t\tthis.request(endpoint, config).then(\n\t\t\t\t(data) => ({ ok: true as const, data }),\n\t\t\t\tasync (error) => ({\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: onError ? await onError(error) : (error as E),\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\tprivate parseEndpoint<T extends EndpointString>(\n\t\tendpoint: T,\n\t): ParseEndpoint<T> {\n\t\tconst [method, ...routeParts] = endpoint.split(' ');\n\t\tconst route = routeParts.join(' ');\n\t\treturn { method: method?.toLowerCase() ?? '', route } as ParseEndpoint<T>;\n\t}\n}\n\nexport function createTypedFetcher<Paths>(options?: FetcherOptions) {\n\tconst fetcher = new TypedFetcher<Paths>(options);\n\tconst fn = <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => fetcher.request(endpoint, config);\n\n\treturn Object.assign(fn, {\n\t\twrap: <E = unknown>(onError?: ErrorTransformer<E>) =>\n\t\t\tObject.assign(fetcher.wrap(onError), fn, {\n\t\t\t\twrap: undefined,\n\t\t\t}),\n\t});\n}\n\nexport type FetchFn = typeof fetch;\n"],"mappings":"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"}
1
+ {"version":3,"file":"fetcher.cjs","names":["methodCalls"],"sources":["../src/fetcher.ts"],"sourcesContent":["import qs from 'qs';\nimport { methodCalls } from './methods';\nimport type {\n\tEndpointString,\n\tErrorTransformer,\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tParseEndpoint,\n\tTypedApiFunction,\n\tTypedEndpoint,\n\tWrappedResult,\n} from './types';\n\nexport type { FetcherOptions, WrappedResult } from './types';\n\nexport class TypedFetcher<Paths> {\n\tprivate baseURL: string;\n\tprivate defaultHeaders: Record<string, string>;\n\tprivate options: FetcherOptions;\n\tprivate fetchFn: FetchFn;\n\n\tstatic getFetchFn(fn?: FetchFn): FetchFn {\n\t\tif (fn) {\n\t\t\treturn fn;\n\t\t}\n\n\t\tif (typeof window !== 'undefined' && typeof window.fetch === 'function') {\n\t\t\treturn window.fetch.bind(window);\n\t\t}\n\n\t\tif (\n\t\t\ttypeof globalThis !== 'undefined' &&\n\t\t\ttypeof globalThis.fetch === 'function'\n\t\t) {\n\t\t\treturn globalThis.fetch.bind(globalThis);\n\t\t}\n\n\t\tthrow new Error('No fetch implementation found');\n\t}\n\n\tconstructor(options: FetcherOptions = {}) {\n\t\tthis.baseURL = options.baseURL || '';\n\t\tthis.defaultHeaders = options.headers || {};\n\t\tthis.options = options;\n\t\tthis.fetchFn = TypedFetcher.getFetchFn(options.fetch);\n\t}\n\n\tasync request<T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> {\n\t\tconst { method, route } = this.parseEndpoint(endpoint);\n\n\t\t// Replace path parameters\n\t\tlet url = route;\n\t\tif (config && 'params' in config && config.params) {\n\t\t\tObject.entries(config.params as Record<string, unknown>).forEach(\n\t\t\t\t([key, value]) => {\n\t\t\t\t\turl = url.replace(`{${key}}`, encodeURIComponent(String(value)));\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Add query parameters\n\t\tif (config && 'query' in config && config.query) {\n\t\t\tconst queryString = qs.stringify(config.query, {\n\t\t\t\tencode: true,\n\t\t\t\tarrayFormat: 'brackets',\n\t\t\t\tskipNulls: true,\n\t\t\t});\n\t\t\tif (queryString) {\n\t\t\t\turl += `?${queryString}`;\n\t\t\t}\n\t\t}\n\n\t\t// Build request configuration\n\t\tlet requestConfig: RequestInit = {\n\t\t\tmethod: method.toUpperCase(),\n\t\t\theaders: {\n\t\t\t\t...this.defaultHeaders,\n\t\t\t\t...((config && 'headers' in config && config.headers) || {}),\n\t\t\t},\n\t\t};\n\n\t\t// Add body if present\n\t\tif (config && 'body' in config && config.body) {\n\t\t\trequestConfig.body = JSON.stringify(config.body);\n\t\t\trequestConfig.headers = {\n\t\t\t\t...requestConfig.headers,\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t};\n\t\t}\n\n\t\t// Apply request interceptor\n\t\tif (this.options.onRequest) {\n\t\t\trequestConfig = await this.options.onRequest(requestConfig);\n\t\t}\n\n\t\ttry {\n\t\t\t// Make the request\n\t\t\tlet response = await this.fetchFn(`${this.baseURL}${url}`, requestConfig);\n\n\t\t\t// Apply response interceptor\n\t\t\tif (this.options.onResponse) {\n\t\t\t\tresponse = await this.options.onResponse(response);\n\t\t\t}\n\n\t\t\t// Handle errors\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow response;\n\t\t\t}\n\n\t\t\t// Handle empty responses (204 No Content, etc.)\n\t\t\tif (\n\t\t\t\tresponse.status === 204 ||\n\t\t\t\tresponse.headers.get('content-length') === '0'\n\t\t\t) {\n\t\t\t\treturn undefined as ExtractEndpointResponse<Paths, T>;\n\t\t\t}\n\n\t\t\t// Parse JSON response\n\t\t\tconst data = await response.json();\n\t\t\treturn data as ExtractEndpointResponse<Paths, T>;\n\t\t} catch (error) {\n\t\t\t// Apply error handler\n\t\t\tif (this.options.onError) {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tawait this.options.onError(error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\twrap<E = unknown>(onError?: ErrorTransformer<E>) {\n\t\treturn <T extends TypedEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t\t): Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>> =>\n\t\t\tthis.request(endpoint, config).then(\n\t\t\t\t(data) => ({ ok: true as const, data }),\n\t\t\t\tasync (error) => ({\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: onError ? await onError(error) : (error as E),\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\tprivate parseEndpoint<T extends EndpointString>(\n\t\tendpoint: T,\n\t): ParseEndpoint<T> {\n\t\tconst [method, ...routeParts] = endpoint.split(' ');\n\t\tconst route = routeParts.join(' ');\n\t\treturn { method: method?.toLowerCase() ?? '', route } as ParseEndpoint<T>;\n\t}\n}\n\nexport function createTypedFetcher<Paths>(options?: FetcherOptions) {\n\tconst fetcher = new TypedFetcher<Paths>(options);\n\tconst fn = <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => fetcher.request(endpoint, config);\n\n\treturn Object.assign(fn, methodCalls<Paths>(fn as TypedApiFunction<Paths>), {\n\t\twrap: <E = unknown>(onError?: ErrorTransformer<E>) =>\n\t\t\tObject.assign(fetcher.wrap(onError), fn, {\n\t\t\t\twrap: undefined,\n\t\t\t}),\n\t});\n}\n\nexport type FetchFn = typeof fetch;\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { ErrorTransformer, ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, TypedEndpoint, WrappedResult } from "./types.cjs";
2
+ import { MethodCalls } from "./methods.cjs";
2
3
  //#region src/fetcher.d.ts
3
4
  export declare class TypedFetcher<Paths> {
4
5
  private baseURL;
@@ -11,7 +12,7 @@ export declare class TypedFetcher<Paths> {
11
12
  wrap<E = unknown>(onError?: ErrorTransformer<E>): <T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>>;
12
13
  private parseEndpoint;
13
14
  }
14
- export declare function createTypedFetcher<Paths>(options?: FetcherOptions): (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>) & {
15
+ export declare function createTypedFetcher<Paths>(options?: FetcherOptions): (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>) & MethodCalls<Paths> & {
15
16
  wrap: <E = unknown>(onError?: ErrorTransformer<E>) => (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T> | undefined) => Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>>) & (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>) & {
16
17
  wrap: undefined;
17
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.d.cts","names":[],"sources":["../src/fetcher.ts"],"mappings":";;qBAca,aAAa;UACjB;UACA;UACA;UACA;SAED,WAAW,KAAK,UAAU;EAmBjC,YAAY,UAAS;EAOf,QAAQ,UAAU,cAAc,QACrC,UAAU,GACV,SAAS,sBAAsB,OAAO,KACpC,QAAQ,wBAAwB,OAAO;EAmF1C,KAAK,aAAa,UAAU,iBAAiB,MACpC,UAAU,cAAc,QAAM,UAC3B,GAAC,SACF,sBAAsB,OAAO,OACpC,QAAQ,cAAc,wBAAwB,OAAO,IAAI;UAUrD;;wBASO,mBAAmB,OAAO,UAAU,mBAEvC,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA;EAIjC,OAAA,aAAW,UAAY,iBAAiB,SA9BvC,UAAU,cAAa,QAAO,UAAA,GAAA,SAAA,sBAAA,OAAA,mBAAA,QAAA,cAAA,wBAAA,OAAA,IAAA,SAwB3B,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA;;;;YAW9B,iBAAiB"}
1
+ {"version":3,"file":"fetcher.d.cts","names":["_$__methods0.MethodCalls"],"sources":["../src/fetcher.ts"],"mappings":";;;qBAgBa,aAAa;UACjB;UACA;UACA;UACA;SAED,WAAW,KAAK,UAAU;EAmBjC,YAAY,UAAS;EAOf,QAAQ,UAAU,cAAc,QACrC,UAAU,GACV,SAAS,sBAAsB,OAAO,KACpC,QAAQ,wBAAwB,OAAO;EAmF1C,KAAK,aAAa,UAAU,iBAAiB,MACpC,UAAU,cAAc,QAAM,UAC3B,GAAC,SACF,sBAAsB,OAAO,OACpC,QAAQ,cAAc,wBAAwB,OAAO,IAAI;UAUrD;;wBASO,mBAAmB,OAAO,UAAU,mBAEvC,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA,OAAAA,YAAA;EAIjC,OAAA,aAAW,UAAY,iBAAiB,SA9BvC,UAAU,cAAa,QAAO,UAAA,GAAA,SAAA,sBAAA,OAAA,mBAAA,QAAA,cAAA,wBAAA,OAAA,IAAA,SAwB3B,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA;;;;YAW9B,iBAAiB"}
@@ -1,4 +1,5 @@
1
1
  import { ErrorTransformer, ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, TypedEndpoint, WrappedResult } from "./types.mjs";
2
+ import { MethodCalls } from "./methods.mjs";
2
3
  //#region src/fetcher.d.ts
3
4
  export declare class TypedFetcher<Paths> {
4
5
  private baseURL;
@@ -11,7 +12,7 @@ export declare class TypedFetcher<Paths> {
11
12
  wrap<E = unknown>(onError?: ErrorTransformer<E>): <T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>>;
12
13
  private parseEndpoint;
13
14
  }
14
- export declare function createTypedFetcher<Paths>(options?: FetcherOptions): (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>) & {
15
+ export declare function createTypedFetcher<Paths>(options?: FetcherOptions): (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>) & MethodCalls<Paths> & {
15
16
  wrap: <E = unknown>(onError?: ErrorTransformer<E>) => (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T> | undefined) => Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>>) & (<T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>) & {
16
17
  wrap: undefined;
17
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.d.mts","names":[],"sources":["../src/fetcher.ts"],"mappings":";;qBAca,aAAa;UACjB;UACA;UACA;UACA;SAED,WAAW,KAAK,UAAU;EAmBjC,YAAY,UAAS;EAOf,QAAQ,UAAU,cAAc,QACrC,UAAU,GACV,SAAS,sBAAsB,OAAO,KACpC,QAAQ,wBAAwB,OAAO;EAmF1C,KAAK,aAAa,UAAU,iBAAiB,MACpC,UAAU,cAAc,QAAM,UAC3B,GAAC,SACF,sBAAsB,OAAO,OACpC,QAAQ,cAAc,wBAAwB,OAAO,IAAI;UAUrD;;wBASO,mBAAmB,OAAO,UAAU,mBAEvC,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA;EAIjC,OAAA,aAAW,UAAY,iBAAiB,SA9BvC,UAAU,cAAa,QAAO,UAAA,GAAA,SAAA,sBAAA,OAAA,mBAAA,QAAA,cAAA,wBAAA,OAAA,IAAA,SAwB3B,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA;;;;YAW9B,iBAAiB"}
1
+ {"version":3,"file":"fetcher.d.mts","names":["_$__methods0.MethodCalls"],"sources":["../src/fetcher.ts"],"mappings":";;;qBAgBa,aAAa;UACjB;UACA;UACA;UACA;SAED,WAAW,KAAK,UAAU;EAmBjC,YAAY,UAAS;EAOf,QAAQ,UAAU,cAAc,QACrC,UAAU,GACV,SAAS,sBAAsB,OAAO,KACpC,QAAQ,wBAAwB,OAAO;EAmF1C,KAAK,aAAa,UAAU,iBAAiB,MACpC,UAAU,cAAc,QAAM,UAC3B,GAAC,SACF,sBAAsB,OAAO,OACpC,QAAQ,cAAc,wBAAwB,OAAO,IAAI;UAUrD;;wBASO,mBAAmB,OAAO,UAAU,mBAEvC,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA,OAAAA,YAAA;EAIjC,OAAA,aAAW,UAAY,iBAAiB,SA9BvC,UAAU,cAAa,QAAO,UAAA,GAAA,SAAA,sBAAA,OAAA,mBAAA,QAAA,cAAA,wBAAA,OAAA,IAAA,SAwB3B,UAAU,cAAc,QAAM,UAC/B,GAAC,SACF,sBAAsB,OAAO,OAAE,QAAA,wBAAA,OAAA;;;;YAW9B,iBAAiB"}
package/dist/fetcher.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { methodCalls } from "./methods.mjs";
1
2
  import qs from "qs";
2
3
  //#region src/fetcher.ts
3
4
  var TypedFetcher = class TypedFetcher {
@@ -78,7 +79,7 @@ var TypedFetcher = class TypedFetcher {
78
79
  function createTypedFetcher(options) {
79
80
  const fetcher = new TypedFetcher(options);
80
81
  const fn = (endpoint, config) => fetcher.request(endpoint, config);
81
- return Object.assign(fn, { wrap: (onError) => Object.assign(fetcher.wrap(onError), fn, { wrap: void 0 }) });
82
+ return Object.assign(fn, methodCalls(fn), { wrap: (onError) => Object.assign(fetcher.wrap(onError), fn, { wrap: void 0 }) });
82
83
  }
83
84
  //#endregion
84
85
  export { TypedFetcher, createTypedFetcher };
@@ -1 +1 @@
1
- {"version":3,"file":"fetcher.mjs","names":[],"sources":["../src/fetcher.ts"],"sourcesContent":["import qs from 'qs';\nimport type {\n\tEndpointString,\n\tErrorTransformer,\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tParseEndpoint,\n\tTypedEndpoint,\n\tWrappedResult,\n} from './types';\n\nexport type { FetcherOptions, WrappedResult } from './types';\n\nexport class TypedFetcher<Paths> {\n\tprivate baseURL: string;\n\tprivate defaultHeaders: Record<string, string>;\n\tprivate options: FetcherOptions;\n\tprivate fetchFn: FetchFn;\n\n\tstatic getFetchFn(fn?: FetchFn): FetchFn {\n\t\tif (fn) {\n\t\t\treturn fn;\n\t\t}\n\n\t\tif (typeof window !== 'undefined' && typeof window.fetch === 'function') {\n\t\t\treturn window.fetch.bind(window);\n\t\t}\n\n\t\tif (\n\t\t\ttypeof globalThis !== 'undefined' &&\n\t\t\ttypeof globalThis.fetch === 'function'\n\t\t) {\n\t\t\treturn globalThis.fetch.bind(globalThis);\n\t\t}\n\n\t\tthrow new Error('No fetch implementation found');\n\t}\n\n\tconstructor(options: FetcherOptions = {}) {\n\t\tthis.baseURL = options.baseURL || '';\n\t\tthis.defaultHeaders = options.headers || {};\n\t\tthis.options = options;\n\t\tthis.fetchFn = TypedFetcher.getFetchFn(options.fetch);\n\t}\n\n\tasync request<T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> {\n\t\tconst { method, route } = this.parseEndpoint(endpoint);\n\n\t\t// Replace path parameters\n\t\tlet url = route;\n\t\tif (config && 'params' in config && config.params) {\n\t\t\tObject.entries(config.params as Record<string, unknown>).forEach(\n\t\t\t\t([key, value]) => {\n\t\t\t\t\turl = url.replace(`{${key}}`, encodeURIComponent(String(value)));\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Add query parameters\n\t\tif (config && 'query' in config && config.query) {\n\t\t\tconst queryString = qs.stringify(config.query, {\n\t\t\t\tencode: true,\n\t\t\t\tarrayFormat: 'brackets',\n\t\t\t\tskipNulls: true,\n\t\t\t});\n\t\t\tif (queryString) {\n\t\t\t\turl += `?${queryString}`;\n\t\t\t}\n\t\t}\n\n\t\t// Build request configuration\n\t\tlet requestConfig: RequestInit = {\n\t\t\tmethod: method.toUpperCase(),\n\t\t\theaders: {\n\t\t\t\t...this.defaultHeaders,\n\t\t\t\t...((config && 'headers' in config && config.headers) || {}),\n\t\t\t},\n\t\t};\n\n\t\t// Add body if present\n\t\tif (config && 'body' in config && config.body) {\n\t\t\trequestConfig.body = JSON.stringify(config.body);\n\t\t\trequestConfig.headers = {\n\t\t\t\t...requestConfig.headers,\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t};\n\t\t}\n\n\t\t// Apply request interceptor\n\t\tif (this.options.onRequest) {\n\t\t\trequestConfig = await this.options.onRequest(requestConfig);\n\t\t}\n\n\t\ttry {\n\t\t\t// Make the request\n\t\t\tlet response = await this.fetchFn(`${this.baseURL}${url}`, requestConfig);\n\n\t\t\t// Apply response interceptor\n\t\t\tif (this.options.onResponse) {\n\t\t\t\tresponse = await this.options.onResponse(response);\n\t\t\t}\n\n\t\t\t// Handle errors\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow response;\n\t\t\t}\n\n\t\t\t// Handle empty responses (204 No Content, etc.)\n\t\t\tif (\n\t\t\t\tresponse.status === 204 ||\n\t\t\t\tresponse.headers.get('content-length') === '0'\n\t\t\t) {\n\t\t\t\treturn undefined as ExtractEndpointResponse<Paths, T>;\n\t\t\t}\n\n\t\t\t// Parse JSON response\n\t\t\tconst data = await response.json();\n\t\t\treturn data as ExtractEndpointResponse<Paths, T>;\n\t\t} catch (error) {\n\t\t\t// Apply error handler\n\t\t\tif (this.options.onError) {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tawait this.options.onError(error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\twrap<E = unknown>(onError?: ErrorTransformer<E>) {\n\t\treturn <T extends TypedEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t\t): Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>> =>\n\t\t\tthis.request(endpoint, config).then(\n\t\t\t\t(data) => ({ ok: true as const, data }),\n\t\t\t\tasync (error) => ({\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: onError ? await onError(error) : (error as E),\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\tprivate parseEndpoint<T extends EndpointString>(\n\t\tendpoint: T,\n\t): ParseEndpoint<T> {\n\t\tconst [method, ...routeParts] = endpoint.split(' ');\n\t\tconst route = routeParts.join(' ');\n\t\treturn { method: method?.toLowerCase() ?? '', route } as ParseEndpoint<T>;\n\t}\n}\n\nexport function createTypedFetcher<Paths>(options?: FetcherOptions) {\n\tconst fetcher = new TypedFetcher<Paths>(options);\n\tconst fn = <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => fetcher.request(endpoint, config);\n\n\treturn Object.assign(fn, {\n\t\twrap: <E = unknown>(onError?: ErrorTransformer<E>) =>\n\t\t\tObject.assign(fetcher.wrap(onError), fn, {\n\t\t\t\twrap: undefined,\n\t\t\t}),\n\t});\n}\n\nexport type FetchFn = typeof fetch;\n"],"mappings":";;AAcA,IAAa,eAAb,MAAa,aAAoB;CAChC;CACA;CACA;CACA;CAEA,OAAO,WAAW,IAAuB;EACxC,IAAI,IACH,OAAO;EAGR,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,UAAU,YAC5D,OAAO,OAAO,MAAM,KAAK,MAAM;EAGhC,IACC,OAAO,eAAe,eACtB,OAAO,WAAW,UAAU,YAE5B,OAAO,WAAW,MAAM,KAAK,UAAU;EAGxC,MAAM,IAAI,MAAM,+BAA+B;CAChD;CAEA,YAAY,UAA0B,CAAC,GAAG;EACzC,KAAK,UAAU,QAAQ,WAAW;EAClC,KAAK,iBAAiB,QAAQ,WAAW,CAAC;EAC1C,KAAK,UAAU;EACf,KAAK,UAAU,aAAa,WAAW,QAAQ,KAAK;CACrD;CAEA,MAAM,QACL,UACA,QAC6C;EAC7C,MAAM,EAAE,QAAQ,UAAU,KAAK,cAAc,QAAQ;EAGrD,IAAI,MAAM;EACV,IAAI,UAAU,YAAY,UAAU,OAAO,QAC1C,OAAO,QAAQ,OAAO,MAAiC,CAAC,CAAC,SACvD,CAAC,KAAK,WAAW;GACjB,MAAM,IAAI,QAAQ,IAAI,IAAI,IAAI,mBAAmB,OAAO,KAAK,CAAC,CAAC;EAChE,CACD;EAID,IAAI,UAAU,WAAW,UAAU,OAAO,OAAO;GAChD,MAAM,cAAc,GAAG,UAAU,OAAO,OAAO;IAC9C,QAAQ;IACR,aAAa;IACb,WAAW;GACZ,CAAC;GACD,IAAI,aACH,OAAO,IAAI;EAEb;EAGA,IAAI,gBAA6B;GAChC,QAAQ,OAAO,YAAY;GAC3B,SAAS;IACR,GAAG,KAAK;IACR,GAAK,UAAU,aAAa,UAAU,OAAO,WAAY,CAAC;GAC3D;EACD;EAGA,IAAI,UAAU,UAAU,UAAU,OAAO,MAAM;GAC9C,cAAc,OAAO,KAAK,UAAU,OAAO,IAAI;GAC/C,cAAc,UAAU;IACvB,GAAG,cAAc;IACjB,gBAAgB;GACjB;EACD;EAGA,IAAI,KAAK,QAAQ,WAChB,gBAAgB,MAAM,KAAK,QAAQ,UAAU,aAAa;EAG3D,IAAI;GAEH,IAAI,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,UAAU,OAAO,aAAa;GAGxE,IAAI,KAAK,QAAQ,YAChB,WAAW,MAAM,KAAK,QAAQ,WAAW,QAAQ;GAIlD,IAAI,CAAC,SAAS,IACb,MAAM;GAIP,IACC,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,gBAAgB,MAAM,KAE3C;GAKD,OAAO,MADY,SAAS,KAAK;EAElC,SAAS,OAAO;GAEf,IAAI,KAAK,QAAQ,SAEhB,MAAM,KAAK,QAAQ,QAAQ,KAAK;GAEjC,MAAM;EACP;CACD;CAEA,KAAkB,SAA+B;EAChD,QACC,UACA,WAEA,KAAK,QAAQ,UAAU,MAAM,CAAC,CAAC,MAC7B,UAAU;GAAE,IAAI;GAAe;EAAK,IACrC,OAAO,WAAW;GACjB,IAAI;GACJ,OAAO,UAAU,MAAM,QAAQ,KAAK,IAAK;EAC1C,EACD;CACF;CAEA,cACC,UACmB;EACnB,MAAM,CAAC,QAAQ,GAAG,cAAc,SAAS,MAAM,GAAG;EAClD,MAAM,QAAQ,WAAW,KAAK,GAAG;EACjC,OAAO;GAAE,QAAQ,QAAQ,YAAY,KAAK;GAAI;EAAM;CACrD;AACD;AAEA,SAAgB,mBAA0B,SAA0B;CACnE,MAAM,UAAU,IAAI,aAAoB,OAAO;CAC/C,MAAM,MACL,UACA,WACI,QAAQ,QAAQ,UAAU,MAAM;CAErC,OAAO,OAAO,OAAO,IAAI,EACxB,OAAoB,YACnB,OAAO,OAAO,QAAQ,KAAK,OAAO,GAAG,IAAI,EACxC,MAAM,KAAA,EACP,CAAC,EACH,CAAC;AACF"}
1
+ {"version":3,"file":"fetcher.mjs","names":[],"sources":["../src/fetcher.ts"],"sourcesContent":["import qs from 'qs';\nimport { methodCalls } from './methods';\nimport type {\n\tEndpointString,\n\tErrorTransformer,\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tParseEndpoint,\n\tTypedApiFunction,\n\tTypedEndpoint,\n\tWrappedResult,\n} from './types';\n\nexport type { FetcherOptions, WrappedResult } from './types';\n\nexport class TypedFetcher<Paths> {\n\tprivate baseURL: string;\n\tprivate defaultHeaders: Record<string, string>;\n\tprivate options: FetcherOptions;\n\tprivate fetchFn: FetchFn;\n\n\tstatic getFetchFn(fn?: FetchFn): FetchFn {\n\t\tif (fn) {\n\t\t\treturn fn;\n\t\t}\n\n\t\tif (typeof window !== 'undefined' && typeof window.fetch === 'function') {\n\t\t\treturn window.fetch.bind(window);\n\t\t}\n\n\t\tif (\n\t\t\ttypeof globalThis !== 'undefined' &&\n\t\t\ttypeof globalThis.fetch === 'function'\n\t\t) {\n\t\t\treturn globalThis.fetch.bind(globalThis);\n\t\t}\n\n\t\tthrow new Error('No fetch implementation found');\n\t}\n\n\tconstructor(options: FetcherOptions = {}) {\n\t\tthis.baseURL = options.baseURL || '';\n\t\tthis.defaultHeaders = options.headers || {};\n\t\tthis.options = options;\n\t\tthis.fetchFn = TypedFetcher.getFetchFn(options.fetch);\n\t}\n\n\tasync request<T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t): Promise<ExtractEndpointResponse<Paths, T>> {\n\t\tconst { method, route } = this.parseEndpoint(endpoint);\n\n\t\t// Replace path parameters\n\t\tlet url = route;\n\t\tif (config && 'params' in config && config.params) {\n\t\t\tObject.entries(config.params as Record<string, unknown>).forEach(\n\t\t\t\t([key, value]) => {\n\t\t\t\t\turl = url.replace(`{${key}}`, encodeURIComponent(String(value)));\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Add query parameters\n\t\tif (config && 'query' in config && config.query) {\n\t\t\tconst queryString = qs.stringify(config.query, {\n\t\t\t\tencode: true,\n\t\t\t\tarrayFormat: 'brackets',\n\t\t\t\tskipNulls: true,\n\t\t\t});\n\t\t\tif (queryString) {\n\t\t\t\turl += `?${queryString}`;\n\t\t\t}\n\t\t}\n\n\t\t// Build request configuration\n\t\tlet requestConfig: RequestInit = {\n\t\t\tmethod: method.toUpperCase(),\n\t\t\theaders: {\n\t\t\t\t...this.defaultHeaders,\n\t\t\t\t...((config && 'headers' in config && config.headers) || {}),\n\t\t\t},\n\t\t};\n\n\t\t// Add body if present\n\t\tif (config && 'body' in config && config.body) {\n\t\t\trequestConfig.body = JSON.stringify(config.body);\n\t\t\trequestConfig.headers = {\n\t\t\t\t...requestConfig.headers,\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t};\n\t\t}\n\n\t\t// Apply request interceptor\n\t\tif (this.options.onRequest) {\n\t\t\trequestConfig = await this.options.onRequest(requestConfig);\n\t\t}\n\n\t\ttry {\n\t\t\t// Make the request\n\t\t\tlet response = await this.fetchFn(`${this.baseURL}${url}`, requestConfig);\n\n\t\t\t// Apply response interceptor\n\t\t\tif (this.options.onResponse) {\n\t\t\t\tresponse = await this.options.onResponse(response);\n\t\t\t}\n\n\t\t\t// Handle errors\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow response;\n\t\t\t}\n\n\t\t\t// Handle empty responses (204 No Content, etc.)\n\t\t\tif (\n\t\t\t\tresponse.status === 204 ||\n\t\t\t\tresponse.headers.get('content-length') === '0'\n\t\t\t) {\n\t\t\t\treturn undefined as ExtractEndpointResponse<Paths, T>;\n\t\t\t}\n\n\t\t\t// Parse JSON response\n\t\t\tconst data = await response.json();\n\t\t\treturn data as ExtractEndpointResponse<Paths, T>;\n\t\t} catch (error) {\n\t\t\t// Apply error handler\n\t\t\tif (this.options.onError) {\n\t\t\t\t// @ts-expect-error\n\t\t\t\tawait this.options.onError(error);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\twrap<E = unknown>(onError?: ErrorTransformer<E>) {\n\t\treturn <T extends TypedEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t\t): Promise<WrappedResult<ExtractEndpointResponse<Paths, T>, E>> =>\n\t\t\tthis.request(endpoint, config).then(\n\t\t\t\t(data) => ({ ok: true as const, data }),\n\t\t\t\tasync (error) => ({\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: onError ? await onError(error) : (error as E),\n\t\t\t\t}),\n\t\t\t);\n\t}\n\n\tprivate parseEndpoint<T extends EndpointString>(\n\t\tendpoint: T,\n\t): ParseEndpoint<T> {\n\t\tconst [method, ...routeParts] = endpoint.split(' ');\n\t\tconst route = routeParts.join(' ');\n\t\treturn { method: method?.toLowerCase() ?? '', route } as ParseEndpoint<T>;\n\t}\n}\n\nexport function createTypedFetcher<Paths>(options?: FetcherOptions) {\n\tconst fetcher = new TypedFetcher<Paths>(options);\n\tconst fn = <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => fetcher.request(endpoint, config);\n\n\treturn Object.assign(fn, methodCalls<Paths>(fn as TypedApiFunction<Paths>), {\n\t\twrap: <E = unknown>(onError?: ErrorTransformer<E>) =>\n\t\t\tObject.assign(fetcher.wrap(onError), fn, {\n\t\t\t\twrap: undefined,\n\t\t\t}),\n\t});\n}\n\nexport type FetchFn = typeof fetch;\n"],"mappings":";;;AAgBA,IAAa,eAAb,MAAa,aAAoB;CAChC;CACA;CACA;CACA;CAEA,OAAO,WAAW,IAAuB;EACxC,IAAI,IACH,OAAO;EAGR,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,UAAU,YAC5D,OAAO,OAAO,MAAM,KAAK,MAAM;EAGhC,IACC,OAAO,eAAe,eACtB,OAAO,WAAW,UAAU,YAE5B,OAAO,WAAW,MAAM,KAAK,UAAU;EAGxC,MAAM,IAAI,MAAM,+BAA+B;CAChD;CAEA,YAAY,UAA0B,CAAC,GAAG;EACzC,KAAK,UAAU,QAAQ,WAAW;EAClC,KAAK,iBAAiB,QAAQ,WAAW,CAAC;EAC1C,KAAK,UAAU;EACf,KAAK,UAAU,aAAa,WAAW,QAAQ,KAAK;CACrD;CAEA,MAAM,QACL,UACA,QAC6C;EAC7C,MAAM,EAAE,QAAQ,UAAU,KAAK,cAAc,QAAQ;EAGrD,IAAI,MAAM;EACV,IAAI,UAAU,YAAY,UAAU,OAAO,QAC1C,OAAO,QAAQ,OAAO,MAAiC,CAAC,CAAC,SACvD,CAAC,KAAK,WAAW;GACjB,MAAM,IAAI,QAAQ,IAAI,IAAI,IAAI,mBAAmB,OAAO,KAAK,CAAC,CAAC;EAChE,CACD;EAID,IAAI,UAAU,WAAW,UAAU,OAAO,OAAO;GAChD,MAAM,cAAc,GAAG,UAAU,OAAO,OAAO;IAC9C,QAAQ;IACR,aAAa;IACb,WAAW;GACZ,CAAC;GACD,IAAI,aACH,OAAO,IAAI;EAEb;EAGA,IAAI,gBAA6B;GAChC,QAAQ,OAAO,YAAY;GAC3B,SAAS;IACR,GAAG,KAAK;IACR,GAAK,UAAU,aAAa,UAAU,OAAO,WAAY,CAAC;GAC3D;EACD;EAGA,IAAI,UAAU,UAAU,UAAU,OAAO,MAAM;GAC9C,cAAc,OAAO,KAAK,UAAU,OAAO,IAAI;GAC/C,cAAc,UAAU;IACvB,GAAG,cAAc;IACjB,gBAAgB;GACjB;EACD;EAGA,IAAI,KAAK,QAAQ,WAChB,gBAAgB,MAAM,KAAK,QAAQ,UAAU,aAAa;EAG3D,IAAI;GAEH,IAAI,WAAW,MAAM,KAAK,QAAQ,GAAG,KAAK,UAAU,OAAO,aAAa;GAGxE,IAAI,KAAK,QAAQ,YAChB,WAAW,MAAM,KAAK,QAAQ,WAAW,QAAQ;GAIlD,IAAI,CAAC,SAAS,IACb,MAAM;GAIP,IACC,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,gBAAgB,MAAM,KAE3C;GAKD,OAAO,MADY,SAAS,KAAK;EAElC,SAAS,OAAO;GAEf,IAAI,KAAK,QAAQ,SAEhB,MAAM,KAAK,QAAQ,QAAQ,KAAK;GAEjC,MAAM;EACP;CACD;CAEA,KAAkB,SAA+B;EAChD,QACC,UACA,WAEA,KAAK,QAAQ,UAAU,MAAM,CAAC,CAAC,MAC7B,UAAU;GAAE,IAAI;GAAe;EAAK,IACrC,OAAO,WAAW;GACjB,IAAI;GACJ,OAAO,UAAU,MAAM,QAAQ,KAAK,IAAK;EAC1C,EACD;CACF;CAEA,cACC,UACmB;EACnB,MAAM,CAAC,QAAQ,GAAG,cAAc,SAAS,MAAM,GAAG;EAClD,MAAM,QAAQ,WAAW,KAAK,GAAG;EACjC,OAAO;GAAE,QAAQ,QAAQ,YAAY,KAAK;GAAI;EAAM;CACrD;AACD;AAEA,SAAgB,mBAA0B,SAA0B;CACnE,MAAM,UAAU,IAAI,aAAoB,OAAO;CAC/C,MAAM,MACL,UACA,WACI,QAAQ,QAAQ,UAAU,MAAM;CAErC,OAAO,OAAO,OAAO,IAAI,YAAmB,EAA6B,GAAG,EAC3E,OAAoB,YACnB,OAAO,OAAO,QAAQ,KAAK,OAAO,GAAG,IAAI,EACxC,MAAM,KAAA,EACP,CAAC,EACH,CAAC;AACF"}
package/dist/index.cjs CHANGED
@@ -1,8 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_methods = require("./methods.cjs");
2
3
  const require_fetcher = require("./fetcher.cjs");
3
4
  const require_auth_fetcher = require("./auth-fetcher.cjs");
4
5
  require("./infer.cjs");
5
6
  require("./types.cjs");
7
+ exports.CALL_METHODS = require_methods.CALL_METHODS;
6
8
  exports.TypedFetcher = require_fetcher.TypedFetcher;
7
9
  exports.createAuthAwareFetcher = require_auth_fetcher.createAuthAwareFetcher;
8
10
  exports.createTypedFetcher = require_fetcher.createTypedFetcher;
11
+ exports.methodCalls = require_methods.methodCalls;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { EndpointString, ErrorTransformer, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, IsConfigRequired, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, QueryEndpoint, RequestConfig, TypedApiFunction, TypedEndpoint, ValidEndpoint, WrappedApiFunction, WrappedResult } from "./types.cjs";
2
2
  import { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, GetEndpointAuth, PublicEndpoints, SecuritySchemeObject, TokenProvider, UsedSecuritySchemes, createAuthAwareFetcher } from "./auth-fetcher.cjs";
3
+ import { CALL_METHODS, CallMethod, MethodCall, MethodCalls, RoutesFor, methodCalls } from "./methods.cjs";
3
4
  import { FetchFn, TypedFetcher, createTypedFetcher } from "./fetcher.cjs";
4
5
  import { InferOpenApi, InferOpenApiFromEndpoint } from "./infer.cjs";
5
- export { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, EndpointString, ErrorTransformer, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetchFn, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, GetEndpointAuth, InferOpenApi, InferOpenApiFromEndpoint, IsConfigRequired, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, PublicEndpoints, QueryEndpoint, RequestConfig, SecuritySchemeObject, TokenProvider, TypedApiFunction, TypedEndpoint, TypedFetcher, UsedSecuritySchemes, ValidEndpoint, WrappedApiFunction, WrappedResult, createAuthAwareFetcher, createTypedFetcher };
6
+ export { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, CALL_METHODS, CallMethod, EndpointString, ErrorTransformer, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetchFn, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, GetEndpointAuth, InferOpenApi, InferOpenApiFromEndpoint, IsConfigRequired, MethodCall, MethodCalls, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, PublicEndpoints, QueryEndpoint, RequestConfig, RoutesFor, SecuritySchemeObject, TokenProvider, TypedApiFunction, TypedEndpoint, TypedFetcher, UsedSecuritySchemes, ValidEndpoint, WrappedApiFunction, WrappedResult, createAuthAwareFetcher, createTypedFetcher, methodCalls };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { EndpointString, ErrorTransformer, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, IsConfigRequired, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, QueryEndpoint, RequestConfig, TypedApiFunction, TypedEndpoint, ValidEndpoint, WrappedApiFunction, WrappedResult } from "./types.mjs";
2
2
  import { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, GetEndpointAuth, PublicEndpoints, SecuritySchemeObject, TokenProvider, UsedSecuritySchemes, createAuthAwareFetcher } from "./auth-fetcher.mjs";
3
+ import { CALL_METHODS, CallMethod, MethodCall, MethodCalls, RoutesFor, methodCalls } from "./methods.mjs";
3
4
  import { FetchFn, TypedFetcher, createTypedFetcher } from "./fetcher.mjs";
4
5
  import { InferOpenApi, InferOpenApiFromEndpoint } from "./infer.mjs";
5
- export { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, EndpointString, ErrorTransformer, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetchFn, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, GetEndpointAuth, InferOpenApi, InferOpenApiFromEndpoint, IsConfigRequired, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, PublicEndpoints, QueryEndpoint, RequestConfig, SecuritySchemeObject, TokenProvider, TypedApiFunction, TypedEndpoint, TypedFetcher, UsedSecuritySchemes, ValidEndpoint, WrappedApiFunction, WrappedResult, createAuthAwareFetcher, createTypedFetcher };
6
+ export { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, CALL_METHODS, CallMethod, EndpointString, ErrorTransformer, ExtractEndpointConfig, ExtractEndpointResponse, ExtractMethod, ExtractPathParams, ExtractQueryParams, ExtractRequestBody, ExtractResponse, FetchFn, FetcherOptions, FilterEndpointByMethod, FilteredRequestConfig, GetEndpointAuth, InferOpenApi, InferOpenApiFromEndpoint, IsConfigRequired, MethodCall, MethodCalls, MutationEndpoint, OpenAPIRoutes, ParseEndpoint, PublicEndpoints, QueryEndpoint, RequestConfig, RoutesFor, SecuritySchemeObject, TokenProvider, TypedApiFunction, TypedEndpoint, TypedFetcher, UsedSecuritySchemes, ValidEndpoint, WrappedApiFunction, WrappedResult, createAuthAwareFetcher, createTypedFetcher, methodCalls };
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
+ import { CALL_METHODS, methodCalls } from "./methods.mjs";
1
2
  import { TypedFetcher, createTypedFetcher } from "./fetcher.mjs";
2
3
  import { createAuthAwareFetcher } from "./auth-fetcher.mjs";
3
4
  import "./infer.mjs";
4
5
  import "./types.mjs";
5
- export { TypedFetcher, createAuthAwareFetcher, createTypedFetcher };
6
+ export { CALL_METHODS, TypedFetcher, createAuthAwareFetcher, createTypedFetcher, methodCalls };
package/dist/infer.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Endpoint, EndpointSchemas } from "@geekmidas/constructs/endpoints";
1
+ import { ConvertRouteParams, Endpoint, EndpointSchemas } from "@geekmidas/constructs/endpoints";
2
2
  import { HttpMethod } from "@geekmidas/constructs/types";
3
3
  import { InferStandardSchema, InferStandardSchemaInput } from "@geekmidas/schema";
4
4
  import { StandardSchemaV1 } from "@standard-schema/spec";
@@ -74,7 +74,7 @@ type InferOperation<TInput extends EndpointSchemas, TOutput extends StandardSche
74
74
  * ```
75
75
  */
76
76
  export type InferOpenApiFromEndpoint<T> = T extends Endpoint<infer TRoute, infer TMethod, infer TInput, infer TOutput, any, any, any> ? {
77
- paths: { [K in TRoute]: InferRouteParameters<TRoute> & { [M in LowercaseMethod<TMethod>]: InferOperation<TInput, TOutput>; }; };
77
+ paths: { [K in ConvertRouteParams<TRoute>]: InferRouteParameters<ConvertRouteParams<TRoute>> & { [M in LowercaseMethod<TMethod>]: InferOperation<TInput, TOutput>; }; };
78
78
  } : never;
79
79
  /**
80
80
  * Infers TypedFetcher-compatible paths structure from multiple endpoints
@@ -1 +1 @@
1
- {"version":3,"file":"infer.d.cts","names":[],"sources":["../src/infer.ts"],"mappings":";;;;;;;;;KAeK,gBAAgB,yBACpB,kCAAkC,eAAe,YAC3C,KAAK,oBAAmB,gBAAgB;;;;KAM1C,gBAAgB,UAAU,cAAc,UAAU;;;;KAKlD,qBAAqB,yBACzB,gBAAgB,gBAAgB;EAG7B;IACC,MAAM,gBAAgB;;;;;;KAOtB,yBAAyB,eAAe,mBAAmB;EAC/D,aAAa;;EAGX;IAMC,OAAO,yBAAyB;;;;;;KAQ/B,eACJ,eAAe,iBACf,gBAAgB,gCACb,yBAAyB;EAC5B,cAAc;IAAiB,YAAY;;IAExC;MAKC,oBAAoB,yBAAyB;;;EAIjD;IACC;MACC,SAAS,gBAAgB;QAEtB,oBAAoB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA+BlC,yBAAyB,KACpC,UAAU,eACH,cACA,eACA,cACA;EAMJ,UACE,KAAK,SAAS,qBAAqB,aAClC,KAAK,gBAAgB,WAAW,eAAe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA2ClD,aAAa,qCACxB,mCAAmC,gBAAgB,QAChD,yBAAyB;EAAiB,aAAa;IACtD;EACG,OAAO;IACT,aAAa;EAAgB,aAAa;;EACvC,OAAO,KAAK;;EACZ,OAAO;IACX,aAAa;EACZ"}
1
+ {"version":3,"file":"infer.d.cts","names":[],"sources":["../src/infer.ts"],"mappings":";;;;;;;;;KAgBK,gBAAgB,yBACpB,kCAAkC,eAAe,YAC3C,KAAK,oBAAmB,gBAAgB;;;;KAM1C,gBAAgB,UAAU,cAAc,UAAU;;;;KAKlD,qBAAqB,yBACzB,gBAAgB,gBAAgB;EAG7B;IACC,MAAM,gBAAgB;;;;;;KAOtB,yBAAyB,eAAe,mBAAmB;EAC/D,aAAa;;EAGX;IAMC,OAAO,yBAAyB;;;;;;KAQ/B,eACJ,eAAe,iBACf,gBAAgB,gCACb,yBAAyB;EAC5B,cAAc;IAAiB,YAAY;;IAExC;MAKC,oBAAoB,yBAAyB;;;EAIjD;IACC;MACC,SAAS,gBAAgB;QAEtB,oBAAoB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA+BlC,yBAAyB,KACpC,UAAU,eACH,cACA,eACA,cACA;EAUJ,UACE,KAAK,mBAAmB,UAAU,qBAClC,mBAAmB,cAElB,KAAK,gBAAgB,WAAW,eAAe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA2ClD,aAAa,qCACxB,mCAAmC,gBAAgB,QAChD,yBAAyB;EAAiB,aAAa;IACtD;EACG,OAAO;IACT,aAAa;EAAgB,aAAa;;EACvC,OAAO,KAAK;;EACZ,OAAO;IACX,aAAa;EACZ"}
package/dist/infer.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Endpoint, EndpointSchemas } from "@geekmidas/constructs/endpoints";
1
+ import { ConvertRouteParams, Endpoint, EndpointSchemas } from "@geekmidas/constructs/endpoints";
2
2
  import { HttpMethod } from "@geekmidas/constructs/types";
3
3
  import { InferStandardSchema, InferStandardSchemaInput } from "@geekmidas/schema";
4
4
  import { StandardSchemaV1 } from "@standard-schema/spec";
@@ -74,7 +74,7 @@ type InferOperation<TInput extends EndpointSchemas, TOutput extends StandardSche
74
74
  * ```
75
75
  */
76
76
  export type InferOpenApiFromEndpoint<T> = T extends Endpoint<infer TRoute, infer TMethod, infer TInput, infer TOutput, any, any, any> ? {
77
- paths: { [K in TRoute]: InferRouteParameters<TRoute> & { [M in LowercaseMethod<TMethod>]: InferOperation<TInput, TOutput>; }; };
77
+ paths: { [K in ConvertRouteParams<TRoute>]: InferRouteParameters<ConvertRouteParams<TRoute>> & { [M in LowercaseMethod<TMethod>]: InferOperation<TInput, TOutput>; }; };
78
78
  } : never;
79
79
  /**
80
80
  * Infers TypedFetcher-compatible paths structure from multiple endpoints
@@ -1 +1 @@
1
- {"version":3,"file":"infer.d.mts","names":[],"sources":["../src/infer.ts"],"mappings":";;;;;;;;;KAeK,gBAAgB,yBACpB,kCAAkC,eAAe,YAC3C,KAAK,oBAAmB,gBAAgB;;;;KAM1C,gBAAgB,UAAU,cAAc,UAAU;;;;KAKlD,qBAAqB,yBACzB,gBAAgB,gBAAgB;EAG7B;IACC,MAAM,gBAAgB;;;;;;KAOtB,yBAAyB,eAAe,mBAAmB;EAC/D,aAAa;;EAGX;IAMC,OAAO,yBAAyB;;;;;;KAQ/B,eACJ,eAAe,iBACf,gBAAgB,gCACb,yBAAyB;EAC5B,cAAc;IAAiB,YAAY;;IAExC;MAKC,oBAAoB,yBAAyB;;;EAIjD;IACC;MACC,SAAS,gBAAgB;QAEtB,oBAAoB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA+BlC,yBAAyB,KACpC,UAAU,eACH,cACA,eACA,cACA;EAMJ,UACE,KAAK,SAAS,qBAAqB,aAClC,KAAK,gBAAgB,WAAW,eAAe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA2ClD,aAAa,qCACxB,mCAAmC,gBAAgB,QAChD,yBAAyB;EAAiB,aAAa;IACtD;EACG,OAAO;IACT,aAAa;EAAgB,aAAa;;EACvC,OAAO,KAAK;;EACZ,OAAO;IACX,aAAa;EACZ"}
1
+ {"version":3,"file":"infer.d.mts","names":[],"sources":["../src/infer.ts"],"mappings":";;;;;;;;;KAgBK,gBAAgB,yBACpB,kCAAkC,eAAe,YAC3C,KAAK,oBAAmB,gBAAgB;;;;KAM1C,gBAAgB,UAAU,cAAc,UAAU;;;;KAKlD,qBAAqB,yBACzB,gBAAgB,gBAAgB;EAG7B;IACC,MAAM,gBAAgB;;;;;;KAOtB,yBAAyB,eAAe,mBAAmB;EAC/D,aAAa;;EAGX;IAMC,OAAO,yBAAyB;;;;;;KAQ/B,eACJ,eAAe,iBACf,gBAAgB,gCACb,yBAAyB;EAC5B,cAAc;IAAiB,YAAY;;IAExC;MAKC,oBAAoB,yBAAyB;;;EAIjD;IACC;MACC,SAAS,gBAAgB;QAEtB,oBAAoB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA+BlC,yBAAyB,KACpC,UAAU,eACH,cACA,eACA,cACA;EAUJ,UACE,KAAK,mBAAmB,UAAU,qBAClC,mBAAmB,cAElB,KAAK,gBAAgB,WAAW,eAAe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA2ClD,aAAa,qCACxB,mCAAmC,gBAAgB,QAChD,yBAAyB;EAAiB,aAAa;IACtD;EACG,OAAO;IACT,aAAa;EAAgB,aAAa;;EACvC,OAAO,KAAK;;EACZ,OAAO;IACX,aAAa;EACZ"}
@@ -0,0 +1,21 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/methods.ts
3
+ /** The HTTP methods a client offers as calls: `api.get(…)`, `api.post(…)`. */
4
+ const CALL_METHODS = [
5
+ "get",
6
+ "post",
7
+ "put",
8
+ "patch",
9
+ "delete",
10
+ "options"
11
+ ];
12
+ /** The method calls for a client, each delegating to `api('METHOD /route', …)`. */
13
+ function methodCalls(fn) {
14
+ const call = (method) => (route, config) => fn(`${method.toUpperCase()} ${route}`, config);
15
+ return Object.fromEntries(CALL_METHODS.map((method) => [method, call(method)]));
16
+ }
17
+ //#endregion
18
+ exports.CALL_METHODS = CALL_METHODS;
19
+ exports.methodCalls = methodCalls;
20
+
21
+ //# sourceMappingURL=methods.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.cjs","names":[],"sources":["../src/methods.ts"],"sourcesContent":["import type {\n\tExtractEndpointResponse,\n\tExtractMethod,\n\tFilteredRequestConfig,\n\tIsConfigRequired,\n\tTypedApiFunction,\n\tTypedEndpoint,\n} from './types';\n\n/** The HTTP methods a client offers as calls: `api.get(…)`, `api.post(…)`. */\nexport const CALL_METHODS = [\n\t'get',\n\t'post',\n\t'put',\n\t'patch',\n\t'delete',\n\t'options',\n] as const;\n\nexport type CallMethod = (typeof CALL_METHODS)[number];\n\n/**\n * The routes that answer `M` — only routes with a `POST` appear in `api.post`,\n * so a route that exists under another method is a type error, not a 405.\n */\nexport type RoutesFor<Paths, M extends CallMethod> = {\n\t[R in keyof Paths]: M extends ExtractMethod<Paths, R> ? R : never;\n}[keyof Paths] &\n\tstring;\n\n/**\n * One method's call: `api.post('/users', { body })`.\n *\n * The second argument has only the keys the endpoint declares, and is required\n * exactly when something in it is — the same rule as `api('POST /users', …)`,\n * which this is sugar over.\n */\nexport type MethodCall<Paths, M extends CallMethod> = <\n\tR extends RoutesFor<Paths, M>,\n>(\n\troute: R,\n\t...args: `${Uppercase<M>} ${R}` extends TypedEndpoint<Paths>\n\t\t? IsConfigRequired<Paths, `${Uppercase<M>} ${R}`> extends true\n\t\t\t? [config: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>]\n\t\t\t: [config?: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>]\n\t\t: never\n) => Promise<ExtractEndpointResponse<Paths, `${Uppercase<M>} ${R}`>>;\n\nexport type MethodCalls<Paths> = {\n\t[M in CallMethod]: MethodCall<Paths, M>;\n};\n\n/** The method calls for a client, each delegating to `api('METHOD /route', …)`. */\nexport function methodCalls<Paths>(\n\tfn: TypedApiFunction<Paths>,\n): MethodCalls<Paths> {\n\tconst call =\n\t\t(method: CallMethod) =>\n\t\t(route: string, config?: unknown): Promise<unknown> =>\n\t\t\t(fn as (endpoint: string, config?: unknown) => Promise<unknown>)(\n\t\t\t\t`${method.toUpperCase()} ${route}`,\n\t\t\t\tconfig,\n\t\t\t);\n\n\treturn Object.fromEntries(\n\t\tCALL_METHODS.map((method) => [method, call(method)]),\n\t) as unknown as MethodCalls<Paths>;\n}\n"],"mappings":";;;AAUA,MAAa,eAAe;CAC3B;CACA;CACA;CACA;CACA;CACA;AACD;;AAoCA,SAAgB,YACf,IACqB;CACrB,MAAM,QACJ,YACA,OAAe,WACd,GACA,GAAG,OAAO,YAAY,EAAE,GAAG,SAC3B,MACD;CAEF,OAAO,OAAO,YACb,aAAa,KAAK,WAAW,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CACpD;AACD"}
@@ -0,0 +1,23 @@
1
+ import { ExtractEndpointResponse, ExtractMethod, FilteredRequestConfig, IsConfigRequired, TypedApiFunction, TypedEndpoint } from "./types.cjs";
2
+ //#region src/methods.d.ts
3
+ /** The HTTP methods a client offers as calls: `api.get(…)`, `api.post(…)`. */
4
+ export declare const CALL_METHODS: readonly ['get', 'post', 'put', 'patch', 'delete', 'options'];
5
+ export type CallMethod = (typeof CALL_METHODS)[number];
6
+ /**
7
+ * The routes that answer `M` — only routes with a `POST` appear in `api.post`,
8
+ * so a route that exists under another method is a type error, not a 405.
9
+ */
10
+ export type RoutesFor<Paths, M extends CallMethod> = { [R in keyof Paths]: M extends ExtractMethod<Paths, R> ? R : never; }[keyof Paths] & string;
11
+ /**
12
+ * One method's call: `api.post('/users', { body })`.
13
+ *
14
+ * The second argument has only the keys the endpoint declares, and is required
15
+ * exactly when something in it is — the same rule as `api('POST /users', …)`,
16
+ * which this is sugar over.
17
+ */
18
+ export type MethodCall<Paths, M extends CallMethod> = <R extends RoutesFor<Paths, M>>(route: R, ...args: `${Uppercase<M>} ${R}` extends TypedEndpoint<Paths> ? IsConfigRequired<Paths, `${Uppercase<M>} ${R}`> extends true ? [config: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>] : [config?: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>] : never) => Promise<ExtractEndpointResponse<Paths, `${Uppercase<M>} ${R}`>>;
19
+ export type MethodCalls<Paths> = { [M in CallMethod]: MethodCall<Paths, M>; };
20
+ /** The method calls for a client, each delegating to `api('METHOD /route', …)`. */
21
+ export declare function methodCalls<Paths>(fn: TypedApiFunction<Paths>): MethodCalls<Paths>;
22
+ //#endregion
23
+ //# sourceMappingURL=methods.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.cts","names":[],"sources":["../src/methods.ts"],"mappings":";;;qBAUa;YASD,qBAAqB;;;;;YAMrB,UAAU,OAAO,UAAU,iBACrC,WAAW,QAAQ,UAAU,cAAc,OAAO,KAAK,mBACjD;;;;;;;;YAUI,WAAW,OAAO,UAAU,eACvC,UAAU,UAAU,OAAO,IAE3B,OAAO,MACJ,SAAS,UAAU,MAAM,YAAY,cAAc,SACnD,iBAAiB,UAAU,UAAU,MAAM,qBACzC,QAAQ,sBAAsB,UAAU,UAAU,MAAM,SACxD,SAAS,sBAAsB,UAAU,UAAU,MAAM,kBAE1D,QAAQ,wBAAwB,UAAU,UAAU,MAAM;YAEnD,YAAY,YACtB,KAAK,aAAa,WAAW,OAAO;;wBAItB,YAAY,OAC3B,IAAI,iBAAiB,SACnB,YAAY"}
@@ -0,0 +1,23 @@
1
+ import { ExtractEndpointResponse, ExtractMethod, FilteredRequestConfig, IsConfigRequired, TypedApiFunction, TypedEndpoint } from "./types.mjs";
2
+ //#region src/methods.d.ts
3
+ /** The HTTP methods a client offers as calls: `api.get(…)`, `api.post(…)`. */
4
+ export declare const CALL_METHODS: readonly ['get', 'post', 'put', 'patch', 'delete', 'options'];
5
+ export type CallMethod = (typeof CALL_METHODS)[number];
6
+ /**
7
+ * The routes that answer `M` — only routes with a `POST` appear in `api.post`,
8
+ * so a route that exists under another method is a type error, not a 405.
9
+ */
10
+ export type RoutesFor<Paths, M extends CallMethod> = { [R in keyof Paths]: M extends ExtractMethod<Paths, R> ? R : never; }[keyof Paths] & string;
11
+ /**
12
+ * One method's call: `api.post('/users', { body })`.
13
+ *
14
+ * The second argument has only the keys the endpoint declares, and is required
15
+ * exactly when something in it is — the same rule as `api('POST /users', …)`,
16
+ * which this is sugar over.
17
+ */
18
+ export type MethodCall<Paths, M extends CallMethod> = <R extends RoutesFor<Paths, M>>(route: R, ...args: `${Uppercase<M>} ${R}` extends TypedEndpoint<Paths> ? IsConfigRequired<Paths, `${Uppercase<M>} ${R}`> extends true ? [config: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>] : [config?: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>] : never) => Promise<ExtractEndpointResponse<Paths, `${Uppercase<M>} ${R}`>>;
19
+ export type MethodCalls<Paths> = { [M in CallMethod]: MethodCall<Paths, M>; };
20
+ /** The method calls for a client, each delegating to `api('METHOD /route', …)`. */
21
+ export declare function methodCalls<Paths>(fn: TypedApiFunction<Paths>): MethodCalls<Paths>;
22
+ //#endregion
23
+ //# sourceMappingURL=methods.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.mts","names":[],"sources":["../src/methods.ts"],"mappings":";;;qBAUa;YASD,qBAAqB;;;;;YAMrB,UAAU,OAAO,UAAU,iBACrC,WAAW,QAAQ,UAAU,cAAc,OAAO,KAAK,mBACjD;;;;;;;;YAUI,WAAW,OAAO,UAAU,eACvC,UAAU,UAAU,OAAO,IAE3B,OAAO,MACJ,SAAS,UAAU,MAAM,YAAY,cAAc,SACnD,iBAAiB,UAAU,UAAU,MAAM,qBACzC,QAAQ,sBAAsB,UAAU,UAAU,MAAM,SACxD,SAAS,sBAAsB,UAAU,UAAU,MAAM,kBAE1D,QAAQ,wBAAwB,UAAU,UAAU,MAAM;YAEnD,YAAY,YACtB,KAAK,aAAa,WAAW,OAAO;;wBAItB,YAAY,OAC3B,IAAI,iBAAiB,SACnB,YAAY"}
@@ -0,0 +1,19 @@
1
+ //#region src/methods.ts
2
+ /** The HTTP methods a client offers as calls: `api.get(…)`, `api.post(…)`. */
3
+ const CALL_METHODS = [
4
+ "get",
5
+ "post",
6
+ "put",
7
+ "patch",
8
+ "delete",
9
+ "options"
10
+ ];
11
+ /** The method calls for a client, each delegating to `api('METHOD /route', …)`. */
12
+ function methodCalls(fn) {
13
+ const call = (method) => (route, config) => fn(`${method.toUpperCase()} ${route}`, config);
14
+ return Object.fromEntries(CALL_METHODS.map((method) => [method, call(method)]));
15
+ }
16
+ //#endregion
17
+ export { CALL_METHODS, methodCalls };
18
+
19
+ //# sourceMappingURL=methods.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.mjs","names":[],"sources":["../src/methods.ts"],"sourcesContent":["import type {\n\tExtractEndpointResponse,\n\tExtractMethod,\n\tFilteredRequestConfig,\n\tIsConfigRequired,\n\tTypedApiFunction,\n\tTypedEndpoint,\n} from './types';\n\n/** The HTTP methods a client offers as calls: `api.get(…)`, `api.post(…)`. */\nexport const CALL_METHODS = [\n\t'get',\n\t'post',\n\t'put',\n\t'patch',\n\t'delete',\n\t'options',\n] as const;\n\nexport type CallMethod = (typeof CALL_METHODS)[number];\n\n/**\n * The routes that answer `M` — only routes with a `POST` appear in `api.post`,\n * so a route that exists under another method is a type error, not a 405.\n */\nexport type RoutesFor<Paths, M extends CallMethod> = {\n\t[R in keyof Paths]: M extends ExtractMethod<Paths, R> ? R : never;\n}[keyof Paths] &\n\tstring;\n\n/**\n * One method's call: `api.post('/users', { body })`.\n *\n * The second argument has only the keys the endpoint declares, and is required\n * exactly when something in it is — the same rule as `api('POST /users', …)`,\n * which this is sugar over.\n */\nexport type MethodCall<Paths, M extends CallMethod> = <\n\tR extends RoutesFor<Paths, M>,\n>(\n\troute: R,\n\t...args: `${Uppercase<M>} ${R}` extends TypedEndpoint<Paths>\n\t\t? IsConfigRequired<Paths, `${Uppercase<M>} ${R}`> extends true\n\t\t\t? [config: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>]\n\t\t\t: [config?: FilteredRequestConfig<Paths, `${Uppercase<M>} ${R}`>]\n\t\t: never\n) => Promise<ExtractEndpointResponse<Paths, `${Uppercase<M>} ${R}`>>;\n\nexport type MethodCalls<Paths> = {\n\t[M in CallMethod]: MethodCall<Paths, M>;\n};\n\n/** The method calls for a client, each delegating to `api('METHOD /route', …)`. */\nexport function methodCalls<Paths>(\n\tfn: TypedApiFunction<Paths>,\n): MethodCalls<Paths> {\n\tconst call =\n\t\t(method: CallMethod) =>\n\t\t(route: string, config?: unknown): Promise<unknown> =>\n\t\t\t(fn as (endpoint: string, config?: unknown) => Promise<unknown>)(\n\t\t\t\t`${method.toUpperCase()} ${route}`,\n\t\t\t\tconfig,\n\t\t\t);\n\n\treturn Object.fromEntries(\n\t\tCALL_METHODS.map((method) => [method, call(method)]),\n\t) as unknown as MethodCalls<Paths>;\n}\n"],"mappings":";;AAUA,MAAa,eAAe;CAC3B;CACA;CACA;CACA;CACA;CACA;AACD;;AAoCA,SAAgB,YACf,IACqB;CACrB,MAAM,QACJ,YACA,OAAe,WACd,GACA,GAAG,OAAO,YAAY,EAAE,GAAG,SAC3B,MACD;CAEF,OAAO,OAAO,YACb,aAAa,KAAK,WAAW,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CACpD;AACD"}
package/dist/types.d.cts CHANGED
@@ -13,12 +13,12 @@ export type ExtractQueryParams<Paths, Route extends OpenAPIRoutes<Paths>, Method
13
13
  };
14
14
  } ? Q : never;
15
15
  export type ExtractRequestBody<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
16
- requestBody?: {
17
- content?: {
18
- 'application/json'?: infer B;
19
- };
16
+ requestBody?: infer RB;
17
+ } ? [NonNullable<RB>] extends [never] ? never : NonNullable<RB> extends {
18
+ content?: {
19
+ 'application/json'?: infer B;
20
20
  };
21
- } ? B : never;
21
+ } ? B : never : never;
22
22
  export type ExtractResponse<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
23
23
  responses?: {
24
24
  200?: {
@@ -58,7 +58,8 @@ export type ExtractEndpointConfig<Paths, T extends EndpointString> = T extends `
58
58
  * Build a request config type where:
59
59
  * - `params` is required if the endpoint has path parameters
60
60
  * - `body` is required if the endpoint has a request body
61
- * - `query` and `headers` are always optional
61
+ * - `query` is required if it has a required key, optional otherwise
62
+ * - `headers` is always optional
62
63
  */
63
64
  export type FilteredRequestConfig<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? BuildRequestConfig<ExtractPathParams<Paths, Route>, ExtractQueryParams<Paths, Route, Lowercase<Method>>, ExtractRequestBody<Paths, Route, Lowercase<Method>>> : never : never : never;
64
65
  /**
@@ -70,8 +71,10 @@ type BuildRequestConfig<TParams, TQuery, TBody> = SimplifyIntersection<([TParams
70
71
  params: TParams;
71
72
  }) & ([TBody] extends [never] ? {} : {
72
73
  body: TBody;
73
- }) & ([TQuery] extends [never] ? {} : {
74
+ }) & ([TQuery] extends [never] ? {} : {} extends TQuery ? {
74
75
  query?: TQuery;
76
+ } : {
77
+ query: TQuery;
75
78
  }) & {
76
79
  headers?: Record<string, string>;
77
80
  }>;
@@ -79,10 +82,12 @@ type BuildRequestConfig<TParams, TQuery, TBody> = SimplifyIntersection<([TParams
79
82
  * Simplify intersection types for better IDE display
80
83
  */
81
84
  type SimplifyIntersection<T> = { [K in keyof T]: T[K]; };
85
+ /** Whether a query has a key the caller must supply. */
86
+ type HasRequiredQuery<TQuery> = [TQuery] extends [never] ? false : {} extends TQuery ? false : true;
82
87
  /**
83
88
  * Check if the config object is required (has any required fields)
84
89
  */
85
- export type IsConfigRequired<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? ExtractPathParams<Paths, Route> extends never ? ExtractRequestBody<Paths, Route, Lowercase<Method>> extends never ? false : true : true : false : false : false;
90
+ export type IsConfigRequired<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? ExtractPathParams<Paths, Route> extends never ? ExtractRequestBody<Paths, Route, Lowercase<Method>> extends never ? HasRequiredQuery<ExtractQueryParams<Paths, Route, Lowercase<Method>>> : true : true : false : false : false;
86
91
  /**
87
92
  * Typed function signature for the API client.
88
93
  * Config is required when endpoint has path params or body.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
package/dist/types.d.mts CHANGED
@@ -13,12 +13,12 @@ export type ExtractQueryParams<Paths, Route extends OpenAPIRoutes<Paths>, Method
13
13
  };
14
14
  } ? Q : never;
15
15
  export type ExtractRequestBody<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
16
- requestBody?: {
17
- content?: {
18
- 'application/json'?: infer B;
19
- };
16
+ requestBody?: infer RB;
17
+ } ? [NonNullable<RB>] extends [never] ? never : NonNullable<RB> extends {
18
+ content?: {
19
+ 'application/json'?: infer B;
20
20
  };
21
- } ? B : never;
21
+ } ? B : never : never;
22
22
  export type ExtractResponse<Paths, Route extends OpenAPIRoutes<Paths>, Method extends ExtractMethod<Paths, Route>> = Paths[Route][Method] extends {
23
23
  responses?: {
24
24
  200?: {
@@ -58,7 +58,8 @@ export type ExtractEndpointConfig<Paths, T extends EndpointString> = T extends `
58
58
  * Build a request config type where:
59
59
  * - `params` is required if the endpoint has path parameters
60
60
  * - `body` is required if the endpoint has a request body
61
- * - `query` and `headers` are always optional
61
+ * - `query` is required if it has a required key, optional otherwise
62
+ * - `headers` is always optional
62
63
  */
63
64
  export type FilteredRequestConfig<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? BuildRequestConfig<ExtractPathParams<Paths, Route>, ExtractQueryParams<Paths, Route, Lowercase<Method>>, ExtractRequestBody<Paths, Route, Lowercase<Method>>> : never : never : never;
64
65
  /**
@@ -70,8 +71,10 @@ type BuildRequestConfig<TParams, TQuery, TBody> = SimplifyIntersection<([TParams
70
71
  params: TParams;
71
72
  }) & ([TBody] extends [never] ? {} : {
72
73
  body: TBody;
73
- }) & ([TQuery] extends [never] ? {} : {
74
+ }) & ([TQuery] extends [never] ? {} : {} extends TQuery ? {
74
75
  query?: TQuery;
76
+ } : {
77
+ query: TQuery;
75
78
  }) & {
76
79
  headers?: Record<string, string>;
77
80
  }>;
@@ -79,10 +82,12 @@ type BuildRequestConfig<TParams, TQuery, TBody> = SimplifyIntersection<([TParams
79
82
  * Simplify intersection types for better IDE display
80
83
  */
81
84
  type SimplifyIntersection<T> = { [K in keyof T]: T[K]; };
85
+ /** Whether a query has a key the caller must supply. */
86
+ type HasRequiredQuery<TQuery> = [TQuery] extends [never] ? false : {} extends TQuery ? false : true;
82
87
  /**
83
88
  * Check if the config object is required (has any required fields)
84
89
  */
85
- export type IsConfigRequired<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? ExtractPathParams<Paths, Route> extends never ? ExtractRequestBody<Paths, Route, Lowercase<Method>> extends never ? false : true : true : false : false : false;
90
+ export type IsConfigRequired<Paths, T extends EndpointString> = T extends `${infer Method} ${infer Route}` ? Route extends OpenAPIRoutes<Paths> ? Lowercase<Method> extends ExtractMethod<Paths, Route> ? ExtractPathParams<Paths, Route> extends never ? ExtractRequestBody<Paths, Route, Lowercase<Method>> extends never ? HasRequiredQuery<ExtractQueryParams<Paths, Route, Lowercase<Method>>> : true : true : false : false : false;
86
91
  /**
87
92
  * Typed function signature for the API client.
88
93
  * Config is required when endpoint has path params or body.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";YAAY,cAAc,eAAe;KAEpC;YASO,cAAc,OAAO,cAAc,cAAc,UAAU,cAChE,MAAM,QACZ;YAGW,kBACX,OACA,cAAc,cAAc,UACzB,MAAM;EACT;IAAe,aAAa;;IAE1B;YAGS,mBACX,OACA,cAAc,cAAc,QAC5B,eAAe,cAAc,OAAO,UACjC,MAAM,OAAO;EAAkB;IAAe,cAAc;;IAC7D;YAGS,mBACX,OACA,cAAc,cAAc,QAC5B,eAAe,cAAc,OAAO,UACjC,MAAM,OAAO;EAAkB,oBAAoB;KAIpD,YAAY,+BAEX,YAAY;EAAc;IAAY,2BAA2B;;IAChE;YAIO,gBACX,OACA,cAAc,cAAc,QAC5B,eAAe,cAAc,OAAO,UACjC,MAAM,OAAO;EAChB;IAAc;MAAQ;QAAY,2BAA2B;;;;IAE3D,IACA,MAAM,OAAO;EACZ;IAAc;MAAQ;QAAY,2BAA2B;;;;IAE7D;YAGQ,cACX,OACA,cAAc,cAAc,QAC5B,eAAe,cAAc,OAAO;EAEpC,SAAS,kBAAkB,OAAO;EAClC,QAAQ,mBAAmB,OAAO,OAAO;EACzC,OAAO,mBAAmB,OAAO,OAAO;EACxC,UAAU;;YAGC,oBAAoB;YAIpB,cAAc,YACxB,eAAe,WACd,UAAU,cAAc,MAAM,QAAQ,iBAAiB,mBAC9C,oBACI,WACb,cAAc,MAAM,QAAQ,sBACvB;YAGI,cAAc,SACzB,cAAc,sBAAqB,MAAK,mBAAmB;YAGhD,uBACX,OACA,yBACG,cAAc,sBAAqB,KACpC,aAAa,qBACZ;YAKQ,cAAc,SAAS,uBAAuB;YAG9C,iBAAiB,SAC1B,uBAAuB,iBACvB,uBAAuB,kBACvB,uBAAuB,gBACvB,uBAAuB;YAEd,cAAc,UAAU,kBACnC,mBAAmB,gBAAgB;EAC9B,QAAQ,UAAU;EAAS,OAAO;;YAG5B,wBACX,OACA,UAAU,kBACP,mBAAmB,gBAAgB,UACpC,cAAc,cAAc,SAC3B,UAAU,gBAAgB,cAAc,OAAO,SAC9C,gBAAgB,OAAO,OAAO,UAAU;YAKjC,sBACX,OACA,UAAU,kBACP,mBAAmB,gBAAgB,UACpC,cAAc,cAAc,SAC3B,UAAU,gBAAgB,cAAc,OAAO,SAC9C,cAAc,OAAO,OAAO,UAAU;;;;;;;;YAY/B,sBACX,OACA,UAAU,kBACP,mBAAmB,gBAAgB,UACpC,cAAc,cAAc,SAC3B,UAAU,gBAAgB,cAAc,OAAO,SAC9C,mBACA,kBAAkB,OAAO,QACzB,mBAAmB,OAAO,OAAO,UAAU,UAC3C,mBAAmB,OAAO,OAAO,UAAU;;;;;;KAW3C,mBAAmB,SAAS,QAAQ,SAAS,uBAE/C;EAAkC,QAAQ;OAEzC;EAAgC,MAAM;OAEtC,0CAEY;EACR,QAAQ;;EACR,OAAO;;EAEZ,UAAU;;;;;KAOR,qBAAqB,QAAQ,WAAW,IAAI,EAAE;;KAG9C,iBAAiB,WAAW,6CAEnB;;;;YAOF,iBACX,OACA,UAAU,kBACP,mBAAmB,gBAAgB,UACpC,cAAc,cAAc,SAC3B,UAAU,gBAAgB,cAAc,OAAO,SAC9C,kBAAkB,OAAO,uBACxB,mBAAmB,OAAO,OAAO,UAAU,yBAC1C,iBACA,mBAAmB,OAAO,OAAO,UAAU;;;;;YAYtC,iBAAiB,UAAU,UAAU,cAAc,QAC9D,UAAU,MACP,MAAM,iBAAiB,OAAO,mBAC7B,QAAQ,sBAAsB,OAAO,OACrC,SAAS,sBAAsB,OAAO,QACtC,QAAQ,wBAAwB,OAAO;iBAE3B;EAChB;EACA,UAAU;EACV,aAAa,QAAQ,gBAAgB,cAAc,QAAQ;EAC3D,cAAc,UAAU,aAAa,WAAW,QAAQ;EACxD,WAAW,OAAO,iBAAiB;EACnC,eAAe;;YAGJ,cAAc,GAAG;EACxB;EAAU,MAAM;;EAChB;EAAW,OAAO;;YAEX,iBAAiB,MAAM,mBAAmB,IAAI,QAAQ;YAEtD,mBAAmB,OAAO,gBACrC,UAAU,cAAc,QAExB,UAAU,MACP,MAAM,iBAAiB,OAAO,mBAC7B,QAAQ,sBAAsB,OAAO,OACrC,SAAS,sBAAsB,OAAO,QACtC,QAAQ,cAAc,wBAAwB,OAAO,IAAI"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekmidas/client",
3
- "version": "10.0.0-alpha.19",
3
+ "version": "10.0.0-alpha.20",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -111,16 +111,16 @@
111
111
  "@types/react-dom": "~19.3.0",
112
112
  "jsdom": "~26.1.0",
113
113
  "msw": "~2.15.0",
114
- "@geekmidas/constructs": "^10.0.0-alpha.19",
115
- "@geekmidas/schema": "^10.0.0-alpha.19"
114
+ "@geekmidas/constructs": "^10.0.0-alpha.20",
115
+ "@geekmidas/schema": "^10.0.0-alpha.20"
116
116
  },
117
117
  "peerDependencies": {
118
118
  "@tanstack/react-query": ">=5.0.0",
119
119
  "react": ">=18.0.0",
120
120
  "react-dom": ">=18.0.0",
121
121
  "zod": ">=4.6.5",
122
- "@geekmidas/constructs": "^10.0.0-alpha.19",
123
- "@geekmidas/schema": "^10.0.0-alpha.19"
122
+ "@geekmidas/constructs": "^10.0.0-alpha.20",
123
+ "@geekmidas/schema": "^10.0.0-alpha.20"
124
124
  },
125
125
  "peerDependenciesMeta": {
126
126
  "@geekmidas/constructs": {