@geekmidas/client 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/auth-fetcher.cjs +2 -3
  2. package/dist/auth-fetcher.cjs.map +1 -1
  3. package/dist/auth-fetcher.d.cts +2 -1
  4. package/dist/auth-fetcher.d.cts.map +1 -0
  5. package/dist/auth-fetcher.d.mts +2 -1
  6. package/dist/auth-fetcher.d.mts.map +1 -0
  7. package/dist/auth-fetcher.mjs +2 -3
  8. package/dist/auth-fetcher.mjs.map +1 -1
  9. package/dist/endpoint-hooks.cjs +10 -5
  10. package/dist/endpoint-hooks.cjs.map +1 -1
  11. package/dist/endpoint-hooks.d.cts +2 -2
  12. package/dist/endpoint-hooks.d.cts.map +1 -0
  13. package/dist/endpoint-hooks.d.mts +2 -2
  14. package/dist/endpoint-hooks.d.mts.map +1 -0
  15. package/dist/endpoint-hooks.mjs +10 -5
  16. package/dist/endpoint-hooks.mjs.map +1 -1
  17. package/dist/{fetcher-DLDD_7Sa.mjs → fetcher-5fnBE7Dk.mjs} +2 -2
  18. package/dist/fetcher-5fnBE7Dk.mjs.map +1 -0
  19. package/dist/{fetcher-KdwHgdAl.cjs → fetcher-CgLEaIAC.cjs} +2 -2
  20. package/dist/fetcher-CgLEaIAC.cjs.map +1 -0
  21. package/dist/fetcher.cjs +1 -1
  22. package/dist/fetcher.d.cts +3 -1
  23. package/dist/fetcher.d.cts.map +1 -0
  24. package/dist/fetcher.d.mts +3 -1
  25. package/dist/fetcher.d.mts.map +1 -0
  26. package/dist/fetcher.mjs +1 -1
  27. package/dist/infer.d.cts.map +1 -0
  28. package/dist/infer.d.mts.map +1 -0
  29. package/dist/openapi-hooks.cjs +3 -5
  30. package/dist/openapi-hooks.cjs.map +1 -1
  31. package/dist/openapi-hooks.d.cts +3 -3
  32. package/dist/openapi-hooks.d.cts.map +1 -0
  33. package/dist/openapi-hooks.d.mts +6 -6
  34. package/dist/openapi-hooks.d.mts.map +1 -0
  35. package/dist/openapi-hooks.mjs +3 -5
  36. package/dist/openapi-hooks.mjs.map +1 -1
  37. package/dist/openapi-types.d.cts.map +1 -0
  38. package/dist/openapi-types.d.mts.map +1 -0
  39. package/dist/openapi.cjs.map +1 -1
  40. package/dist/openapi.mjs.map +1 -1
  41. package/dist/react-query.cjs +1 -1
  42. package/dist/react-query.cjs.map +1 -1
  43. package/dist/react-query.d.cts +3 -1
  44. package/dist/react-query.d.cts.map +1 -0
  45. package/dist/react-query.d.mts +10 -8
  46. package/dist/react-query.d.mts.map +1 -0
  47. package/dist/react-query.mjs +1 -1
  48. package/dist/react-query.mjs.map +1 -1
  49. package/dist/{types-D4OSWveN.d.cts → types-4K4N-Fl1.d.cts} +8 -6
  50. package/dist/types-4K4N-Fl1.d.cts.map +1 -0
  51. package/dist/{types-Cdv1XAWr.d.mts → types-hhkZWjQn.d.mts} +8 -6
  52. package/dist/types-hhkZWjQn.d.mts.map +1 -0
  53. package/dist/types.d.cts +1 -1
  54. package/dist/types.d.mts +1 -1
  55. package/package.json +6 -5
  56. package/src/__tests__/auth-fetcher.spec.ts +505 -0
  57. package/src/__tests__/endpoint-hooks.spec.tsx +348 -348
  58. package/src/__tests__/fetcher.spec.ts +403 -403
  59. package/src/__tests__/infer.integration.spec.ts +171 -171
  60. package/src/__tests__/infer.spec.ts +182 -182
  61. package/src/__tests__/method-restrictions.spec.tsx +165 -165
  62. package/src/__tests__/openapi-hooks.spec.tsx +536 -537
  63. package/src/__tests__/react-query-infinite.spec.tsx +989 -989
  64. package/src/__tests__/react-query-invalidation.spec.tsx +223 -222
  65. package/src/__tests__/react-query.spec.tsx +567 -567
  66. package/src/__tests__/setup.ts +260 -260
  67. package/src/__tests__/types.spec.ts +127 -127
  68. package/src/__tests__/url-parsing.spec.ts +191 -191
  69. package/src/auth-fetcher.ts +160 -162
  70. package/src/endpoint-hooks.ts +151 -150
  71. package/src/fetcher.ts +163 -163
  72. package/src/infer.ts +64 -63
  73. package/src/openapi-hooks.ts +146 -146
  74. package/src/openapi-types.d.ts +428 -428
  75. package/src/openapi.json +593 -593
  76. package/src/react-query.ts +281 -281
  77. package/src/types.ts +124 -125
  78. package/tsconfig.json +12 -0
  79. package/dist/fetcher-DLDD_7Sa.mjs.map +0 -1
  80. package/dist/fetcher-KdwHgdAl.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- const require_fetcher = require('./fetcher-KdwHgdAl.cjs');
1
+ const require_fetcher = require('./fetcher-CgLEaIAC.cjs');
2
2
 
3
3
  //#region src/auth-fetcher.ts
4
4
  /**
@@ -41,7 +41,7 @@ function createAuthAwareFetcher(options) {
41
41
  if (schemeName) {
42
42
  const scheme = securitySchemes[schemeName];
43
43
  const strategy = authStrategies[schemeName];
44
- if (strategy) authHeaders = await resolveAuthHeaders(strategy, scheme);
44
+ if (strategy && scheme) authHeaders = await resolveAuthHeaders(strategy, scheme);
45
45
  }
46
46
  const existingHeaders = config && "headers" in config && config.headers ? config.headers : {};
47
47
  const mergedConfig = {
@@ -68,7 +68,6 @@ async function resolveAuthHeaders(strategy, scheme) {
68
68
  return {};
69
69
  }
70
70
  case "iam": return {};
71
- case "none":
72
71
  default: return {};
73
72
  }
74
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth-fetcher.cjs","names":["options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n baseURL: string;\n }","TypedFetcher","endpoint: T","config?: FilteredRequestConfig<Paths, T>","authHeaders: Record<string, string>","strategy: AuthStrategy","scheme: SecuritySchemeObject"],"sources":["../src/auth-fetcher.ts"],"sourcesContent":["import { TypedFetcher } from './fetcher';\nimport type {\n ExtractEndpointResponse,\n FetcherOptions,\n FilteredRequestConfig,\n TypedApiFunction,\n TypedEndpoint,\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 type: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';\n description?: string;\n name?: string;\n in?: 'query' | 'header' | 'cookie';\n scheme?: string;\n bearerFormat?: string;\n flows?: Record<string, unknown>;\n openIdConnectUrl?: string;\n [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 EndpointAuth 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 /**\n * Get a valid access token, refreshing if necessary.\n */\n getValidAccessToken(): Promise<string | null>;\n\n /**\n * Create Authorization headers from the current token.\n */\n createValidAuthHeaders(): Promise<Record<string, string>>;\n}\n\n/**\n * Interface for API key providers.\n */\nexport interface ApiKeyProvider {\n /**\n * Get the API key value.\n */\n getApiKey(): Promise<string> | string;\n}\n\n/**\n * Interface for AWS SigV4 request signing.\n */\nexport interface AwsSigner {\n /**\n * Sign a request with AWS SigV4.\n * @param url - The request URL\n * @param init - The request init object\n * @returns Headers to add to the request\n */\n sign(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 | { type: 'bearer'; tokenProvider: TokenProvider }\n | { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }\n | { type: 'iam'; signer: AwsSigner }\n | { 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 EndpointAuth extends Record<string, string | null>,\n SecuritySchemes extends Record<string, SecuritySchemeObject>,\n> extends Omit<FetcherOptions, 'onRequest'> {\n /**\n * Runtime map of endpoints to their required auth scheme.\n * Generated by `gkm openapi --ts`.\n */\n endpointAuth: EndpointAuth;\n\n /**\n * Security scheme definitions.\n * Generated by `gkm openapi --ts`.\n */\n securitySchemes: SecuritySchemes;\n\n /**\n * Auth strategies for security schemes that are actually used.\n * Only schemes referenced in endpointAuth are required.\n *\n * @example\n * ```typescript\n * // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }\n * // Then authStrategies must include strategies for 'jwt' and 'iam'\n * authStrategies: {\n * jwt: { type: 'bearer', tokenProvider },\n * iam: { type: 'iam', signer: awsSigner },\n * }\n * ```\n */\n authStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;\n\n /**\n * Optional request interceptor (runs after auth headers are added).\n */\n onRequest?: (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 Paths,\n EndpointAuth extends Record<string, string | null> = Record<\n string,\n string | null\n >,\n SecuritySchemes extends Record<string, SecuritySchemeObject> = Record<\n string,\n SecuritySchemeObject\n >,\n>(\n options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n baseURL: string;\n },\n): TypedApiFunction<Paths> {\n const {\n endpointAuth,\n securitySchemes,\n authStrategies,\n onRequest: userOnRequest,\n ...fetcherOptions\n } = options;\n\n // Create base fetcher with user's onRequest if provided\n const baseFetcher = new TypedFetcher<Paths>({\n ...fetcherOptions,\n onRequest: userOnRequest,\n });\n\n const fetcher = async <T extends TypedEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ): Promise<ExtractEndpointResponse<Paths, T>> => {\n // Look up auth requirement for this endpoint\n const schemeName = endpointAuth[endpoint as keyof EndpointAuth] as\n | string\n | null;\n\n let authHeaders: Record<string, string> = {};\n\n if (schemeName) {\n const scheme = securitySchemes[schemeName as keyof SecuritySchemes];\n // Since authStrategies is now required to have all used schemes,\n // we can safely access it - TypeScript ensures the strategy exists\n const strategy =\n authStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];\n\n if (strategy) {\n authHeaders = await resolveAuthHeaders(strategy, scheme);\n }\n }\n\n // Merge auth headers with config headers\n const existingHeaders =\n config && 'headers' in config && config.headers\n ? (config.headers as Record<string, string>)\n : {};\n\n const mergedConfig = {\n ...config,\n headers: {\n ...authHeaders,\n ...existingHeaders,\n },\n } as unknown as FilteredRequestConfig<Paths, T>;\n\n return baseFetcher.request(endpoint, mergedConfig);\n };\n\n return fetcher as TypedApiFunction<Paths>;\n}\n\n/**\n * Resolves auth headers based on the strategy and scheme.\n */\nasync function resolveAuthHeaders(\n strategy: AuthStrategy,\n scheme: SecuritySchemeObject,\n): Promise<Record<string, string>> {\n switch (strategy.type) {\n case 'bearer': {\n return strategy.tokenProvider.createValidAuthHeaders();\n }\n\n case 'apiKey': {\n const apiKey = await strategy.apiKeyProvider.getApiKey();\n const headerName = strategy.headerName || scheme.name || 'X-API-Key';\n\n if (scheme.in === 'header' || !scheme.in) {\n return { [headerName]: apiKey };\n }\n // Note: query and cookie API keys are handled differently\n // For now, we only support header-based API keys\n return {};\n }\n\n case 'iam': {\n // IAM signing requires the full URL and request config\n // This is a simplified version - full implementation would need\n // access to the complete request\n // For now, return empty - the actual signing should be done\n // in a custom onRequest interceptor if needed\n return {};\n }\n\n case 'none':\n default:\n return {};\n }\n}\n\n/**\n * Type helper to extract the security scheme ID from an endpoint.\n */\nexport type GetEndpointAuth<\n EndpointAuth extends Record<string, string | null>,\n Endpoint extends keyof EndpointAuth,\n> = EndpointAuth[Endpoint];\n\n/**\n * Type helper to get all authenticated endpoints.\n */\nexport type AuthenticatedEndpoints<\n EndpointAuth extends Record<string, string | null>,\n> = {\n [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 EndpointAuth extends Record<string, string | null>,\n> = {\n [K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;\n}[keyof EndpointAuth];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0JA,SAAgB,uBAWdA,SAGyB;CACzB,MAAM,EACJ,cACA,iBACA,gBACA,WAAW,cACX,GAAG,gBACJ,GAAG;CAGJ,MAAM,cAAc,IAAIC,6BAAoB;EAC1C,GAAG;EACH,WAAW;CACZ;CAED,MAAM,UAAU,OACdC,UACAC,WAC+C;EAE/C,MAAM,aAAa,aAAa;EAIhC,IAAIC,cAAsC,CAAE;AAE5C,MAAI,YAAY;GACd,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACJ,eAAe;AAEjB,OAAI,SACF,eAAc,MAAM,mBAAmB,UAAU,OAAO;EAE3D;EAGD,MAAM,kBACJ,UAAU,aAAa,UAAU,OAAO,UACnC,OAAO,UACR,CAAE;EAER,MAAM,eAAe;GACnB,GAAG;GACH,SAAS;IACP,GAAG;IACH,GAAG;GACJ;EACF;AAED,SAAO,YAAY,QAAQ,UAAU,aAAa;CACnD;AAED,QAAO;AACR;;;;AAKD,eAAe,mBACbC,UACAC,QACiC;AACjC,SAAQ,SAAS,MAAjB;EACE,KAAK,SACH,QAAO,SAAS,cAAc,wBAAwB;EAGxD,KAAK,UAAU;GACb,MAAM,SAAS,MAAM,SAAS,eAAe,WAAW;GACxD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;AAEzD,OAAI,OAAO,OAAO,aAAa,OAAO,GACpC,QAAO,GAAG,aAAa,OAAQ;AAIjC,UAAO,CAAE;EACV;EAED,KAAK,MAMH,QAAO,CAAE;EAGX,KAAK;EACL,QACE,QAAO,CAAE;CACZ;AACF"}
1
+ {"version":3,"file":"auth-fetcher.cjs","names":["options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n\t\tbaseURL: string;\n\t}","TypedFetcher","endpoint: T","config?: FilteredRequestConfig<Paths, T>","authHeaders: Record<string, string>","strategy: AuthStrategy","scheme: SecuritySchemeObject"],"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,uBAWfA,SAG0B;CAC1B,MAAM,EACL,cACA,iBACA,gBACA,WAAW,cACX,GAAG,gBACH,GAAG;CAGJ,MAAM,cAAc,IAAIC,6BAAoB;EAC3C,GAAG;EACH,WAAW;CACX;CAED,MAAM,UAAU,OACfC,UACAC,WACgD;EAEhD,MAAM,aAAa,aAAa;EAIhC,IAAIC,cAAsC,CAAE;AAE5C,MAAI,YAAY;GACf,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACL,eAAe;AAEhB,OAAI,YAAY,OACf,eAAc,MAAM,mBAAmB,UAAU,OAAO;EAEzD;EAGD,MAAM,kBACL,UAAU,aAAa,UAAU,OAAO,UACpC,OAAO,UACR,CAAE;EAEN,MAAM,eAAe;GACpB,GAAG;GACH,SAAS;IACR,GAAG;IACH,GAAG;GACH;EACD;AAED,SAAO,YAAY,QAAQ,UAAU,aAAa;CAClD;AAED,QAAO;AACP;;;;AAKD,eAAe,mBACdC,UACAC,QACkC;AAClC,SAAQ,SAAS,MAAjB;EACC,KAAK,SACJ,QAAO,SAAS,cAAc,wBAAwB;EAGvD,KAAK,UAAU;GACd,MAAM,SAAS,MAAM,SAAS,eAAe,WAAW;GACxD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;AAEzD,OAAI,OAAO,OAAO,aAAa,OAAO,GACrC,QAAO,GAAG,aAAa,OAAQ;AAIhC,UAAO,CAAE;EACT;EAED,KAAK,MAMJ,QAAO,CAAE;EAEV,QACC,QAAO,CAAE;CACV;AACD"}
@@ -1,4 +1,4 @@
1
- import { FetcherOptions, TypedApiFunction } from "./types-D4OSWveN.cjs";
1
+ import { FetcherOptions, TypedApiFunction } from "./types-4K4N-Fl1.cjs";
2
2
 
3
3
  //#region src/auth-fetcher.d.ts
4
4
 
@@ -152,6 +152,7 @@ type AuthenticatedEndpoints<EndpointAuth extends Record<string, string | null>>
152
152
  * Type helper to get all public endpoints.
153
153
  */
154
154
  type PublicEndpoints<EndpointAuth extends Record<string, string | null>> = { [K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never }[keyof EndpointAuth];
155
+ //# sourceMappingURL=auth-fetcher.d.ts.map
155
156
  //#endregion
156
157
  export { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, FetcherOptions, GetEndpointAuth, PublicEndpoints, SecuritySchemeObject, TokenProvider, UsedSecuritySchemes, createAuthAwareFetcher };
157
158
  //# sourceMappingURL=auth-fetcher.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-fetcher.d.cts","names":[],"sources":["../src/auth-fetcher.ts"],"sourcesContent":[],"mappings":";;;;;AAcA;AAgBA;AAA+B,UAhBd,oBAAA,CAgBc;EAAA,IACT,EAAA,QAAA,GAAA,MAAA,GAAA,WAAA,GAAA,QAAA,GAAA,eAAA;EAAM,WACZ,CAAA,EAAA,MAAA;EAAY,IAAO,CAAA,EAAA,MAAA;EAAY,EAAA,CAA3C,EAAA,OAAA,GAAA,QAAA,GAAA,QAAA;EAAW,MAAA,CAAA,EAAA,MAAA;EAME,YAAA,CAAA,EAAA,MAAa;EAAA,KAAA,CAAA,EAjBrB,MAiBqB,CAAA,MAAA,EAAA,OAAA,CAAA;EAAA,gBAIN,CAAA,EAAA,MAAA;EAAO,CAAA,GAKI,EAAA,MAAA,CAAA,EAAA,OAAA;;AAAD;AAMlC;AAUA;;AAOyB,KAxCb,mBAwCa,CAAA,qBAvCH,MAuCG,CAAA,MAAA,EAAA,MAAA,GAAA,IAAA,CAAA,CAAA,GAtCrB,WAsCqB,CAtCT,YAsCS,CAAA,MAtCU,YAsCV,CAAA,CAAA;;;AAAqB;AAM9C;AAAwB,UAtCP,aAAA,CAsCO;EAAA;;;EAGW,mBAAA,EAAA,EArCX,OAqCW,CAAA,MAAA,GAAA,IAAA,CAAA;EASlB;;;EACW,sBACY,EAAA,EA3Cb,OA2Ca,CA3CL,MA2CK,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;;;;AA4BI,UAjE3B,cAAA,CAiE2B;EAAY;;;EAAjC,SAKD,EAAA,EAlER,OAkEQ,CAAA,MAAA,CAAA,GAAA,MAAA;;;;;AAhCR,UA5BG,SAAA,CA4BH;EA+DE;;;;;;EAMe,IAE7B,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,EA5FuB,WA4FvB,CAAA,EA5FqC,OA4FrC,CA5F6C,MA4F7C,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;;;;AAMkB,KA5FR,YAAA,GA4FQ;EAAK,IAAtB,EAAA,QAAA;EAAgB,aAAA,EA3FiB,aA2FjB;AAkGnB,CAAA,GAAY;EAAe,IAAA,EAAA,QAAA;EAAA,cACL,EA7Le,cA6Lf;EAAM,UACJ,CAAA,EAAA,MAAA;CAAY,GAAA;EACpB,IAAC,EAAA,KAAA;EAAQ,MAAA,EA9LC,SA8LD;AAKzB,CAAA,GAAY;EAAsB,IAAA,EAAA,MAAA;CAAA;;;;;;AAId;AAKR,UAnMK,kBAmMU,CAAA,qBAlML,MAkMK,CAAA,MAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EAAA,wBAjMF,MAiME,CAAA,MAAA,EAjMa,oBAiMb,CAAA,CAAA,SAhMjB,IAgMiB,CAhMZ,cAgMY,EAAA,WAAA,CAAA,CAAA;EAAA;;;;EAGa,YAAC,EA9L1B,YA8L0B;EAAC;;AACtB;;mBAzLF;;;;;;;;;;;;;;;kBAgBD,OAAO,oBAAoB,eAAe;;;;uBAKrC,gBAAgB,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+B5C,mDAEM,gCAAgC,uDAI7B,eAAe,wBAAwB,eAE9D,gCAGQ,mBAAmB,cAAc;;IAGxC,iBAAiB;;;;KAkGR,qCACU,sDACE,gBACpB,aAAa;;;;KAKL,4CACU,+CAET,eAAe,aAAa,0BAA0B,UAC3D;;;;KAKI,qCACU,+CAET,eAAe,aAAa,kBAAkB,kBACnD"}
@@ -1,4 +1,4 @@
1
- import { FetcherOptions, TypedApiFunction } from "./types-Cdv1XAWr.mjs";
1
+ import { FetcherOptions, TypedApiFunction } from "./types-hhkZWjQn.mjs";
2
2
 
3
3
  //#region src/auth-fetcher.d.ts
4
4
 
@@ -152,6 +152,7 @@ type AuthenticatedEndpoints<EndpointAuth extends Record<string, string | null>>
152
152
  * Type helper to get all public endpoints.
153
153
  */
154
154
  type PublicEndpoints<EndpointAuth extends Record<string, string | null>> = { [K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never }[keyof EndpointAuth];
155
+ //# sourceMappingURL=auth-fetcher.d.ts.map
155
156
  //#endregion
156
157
  export { ApiKeyProvider, AuthFetcherOptions, AuthStrategy, AuthenticatedEndpoints, AwsSigner, FetcherOptions, GetEndpointAuth, PublicEndpoints, SecuritySchemeObject, TokenProvider, UsedSecuritySchemes, createAuthAwareFetcher };
157
158
  //# sourceMappingURL=auth-fetcher.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-fetcher.d.mts","names":[],"sources":["../src/auth-fetcher.ts"],"sourcesContent":[],"mappings":";;;;;AAcA;AAgBA;AAA+B,UAhBd,oBAAA,CAgBc;EAAA,IACT,EAAA,QAAA,GAAA,MAAA,GAAA,WAAA,GAAA,QAAA,GAAA,eAAA;EAAM,WACZ,CAAA,EAAA,MAAA;EAAY,IAAO,CAAA,EAAA,MAAA;EAAY,EAAA,CAA3C,EAAA,OAAA,GAAA,QAAA,GAAA,QAAA;EAAW,MAAA,CAAA,EAAA,MAAA;EAME,YAAA,CAAA,EAAA,MAAa;EAAA,KAAA,CAAA,EAjBrB,MAiBqB,CAAA,MAAA,EAAA,OAAA,CAAA;EAAA,gBAIN,CAAA,EAAA,MAAA;EAAO,CAAA,GAKI,EAAA,MAAA,CAAA,EAAA,OAAA;;AAAD;AAMlC;AAUA;;AAOyB,KAxCb,mBAwCa,CAAA,qBAvCH,MAuCG,CAAA,MAAA,EAAA,MAAA,GAAA,IAAA,CAAA,CAAA,GAtCrB,WAsCqB,CAtCT,YAsCS,CAAA,MAtCU,YAsCV,CAAA,CAAA;;;AAAqB;AAM9C;AAAwB,UAtCP,aAAA,CAsCO;EAAA;;;EAGW,mBAAA,EAAA,EArCX,OAqCW,CAAA,MAAA,GAAA,IAAA,CAAA;EASlB;;;EACW,sBACY,EAAA,EA3Cb,OA2Ca,CA3CL,MA2CK,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;;;;AA4BI,UAjE3B,cAAA,CAiE2B;EAAY;;;EAAjC,SAKD,EAAA,EAlER,OAkEQ,CAAA,MAAA,CAAA,GAAA,MAAA;;;;;AAhCR,UA5BG,SAAA,CA4BH;EA+DE;;;;;;EAMe,IAE7B,CAAA,GAAA,EAAA,MAAA,EAAA,IAAA,EA5FuB,WA4FvB,CAAA,EA5FqC,OA4FrC,CA5F6C,MA4F7C,CAAA,MAAA,EAAA,MAAA,CAAA,CAAA;;;;;AAMkB,KA5FR,YAAA,GA4FQ;EAAK,IAAtB,EAAA,QAAA;EAAgB,aAAA,EA3FiB,aA2FjB;AAkGnB,CAAA,GAAY;EAAe,IAAA,EAAA,QAAA;EAAA,cACL,EA7Le,cA6Lf;EAAM,UACJ,CAAA,EAAA,MAAA;CAAY,GAAA;EACpB,IAAC,EAAA,KAAA;EAAQ,MAAA,EA9LC,SA8LD;AAKzB,CAAA,GAAY;EAAsB,IAAA,EAAA,MAAA;CAAA;;;;;;AAId;AAKR,UAnMK,kBAmMU,CAAA,qBAlML,MAkMK,CAAA,MAAA,EAAA,MAAA,GAAA,IAAA,CAAA,EAAA,wBAjMF,MAiME,CAAA,MAAA,EAjMa,oBAiMb,CAAA,CAAA,SAhMjB,IAgMiB,CAhMZ,cAgMY,EAAA,WAAA,CAAA,CAAA;EAAA;;;;EAGa,YAAC,EA9L1B,YA8L0B;EAAC;;AACtB;;mBAzLF;;;;;;;;;;;;;;;kBAgBD,OAAO,oBAAoB,eAAe;;;;uBAKrC,gBAAgB,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+B5C,mDAEM,gCAAgC,uDAI7B,eAAe,wBAAwB,eAE9D,gCAGQ,mBAAmB,cAAc;;IAGxC,iBAAiB;;;;KAkGR,qCACU,sDACE,gBACpB,aAAa;;;;KAKL,4CACU,+CAET,eAAe,aAAa,0BAA0B,UAC3D;;;;KAKI,qCACU,+CAET,eAAe,aAAa,kBAAkB,kBACnD"}
@@ -1,4 +1,4 @@
1
- import { TypedFetcher } from "./fetcher-DLDD_7Sa.mjs";
1
+ import { TypedFetcher } from "./fetcher-5fnBE7Dk.mjs";
2
2
 
3
3
  //#region src/auth-fetcher.ts
4
4
  /**
@@ -41,7 +41,7 @@ function createAuthAwareFetcher(options) {
41
41
  if (schemeName) {
42
42
  const scheme = securitySchemes[schemeName];
43
43
  const strategy = authStrategies[schemeName];
44
- if (strategy) authHeaders = await resolveAuthHeaders(strategy, scheme);
44
+ if (strategy && scheme) authHeaders = await resolveAuthHeaders(strategy, scheme);
45
45
  }
46
46
  const existingHeaders = config && "headers" in config && config.headers ? config.headers : {};
47
47
  const mergedConfig = {
@@ -68,7 +68,6 @@ async function resolveAuthHeaders(strategy, scheme) {
68
68
  return {};
69
69
  }
70
70
  case "iam": return {};
71
- case "none":
72
71
  default: return {};
73
72
  }
74
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth-fetcher.mjs","names":["options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n baseURL: string;\n }","endpoint: T","config?: FilteredRequestConfig<Paths, T>","authHeaders: Record<string, string>","strategy: AuthStrategy","scheme: SecuritySchemeObject"],"sources":["../src/auth-fetcher.ts"],"sourcesContent":["import { TypedFetcher } from './fetcher';\nimport type {\n ExtractEndpointResponse,\n FetcherOptions,\n FilteredRequestConfig,\n TypedApiFunction,\n TypedEndpoint,\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 type: 'apiKey' | 'http' | 'mutualTLS' | 'oauth2' | 'openIdConnect';\n description?: string;\n name?: string;\n in?: 'query' | 'header' | 'cookie';\n scheme?: string;\n bearerFormat?: string;\n flows?: Record<string, unknown>;\n openIdConnectUrl?: string;\n [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 EndpointAuth 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 /**\n * Get a valid access token, refreshing if necessary.\n */\n getValidAccessToken(): Promise<string | null>;\n\n /**\n * Create Authorization headers from the current token.\n */\n createValidAuthHeaders(): Promise<Record<string, string>>;\n}\n\n/**\n * Interface for API key providers.\n */\nexport interface ApiKeyProvider {\n /**\n * Get the API key value.\n */\n getApiKey(): Promise<string> | string;\n}\n\n/**\n * Interface for AWS SigV4 request signing.\n */\nexport interface AwsSigner {\n /**\n * Sign a request with AWS SigV4.\n * @param url - The request URL\n * @param init - The request init object\n * @returns Headers to add to the request\n */\n sign(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 | { type: 'bearer'; tokenProvider: TokenProvider }\n | { type: 'apiKey'; apiKeyProvider: ApiKeyProvider; headerName?: string }\n | { type: 'iam'; signer: AwsSigner }\n | { 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 EndpointAuth extends Record<string, string | null>,\n SecuritySchemes extends Record<string, SecuritySchemeObject>,\n> extends Omit<FetcherOptions, 'onRequest'> {\n /**\n * Runtime map of endpoints to their required auth scheme.\n * Generated by `gkm openapi --ts`.\n */\n endpointAuth: EndpointAuth;\n\n /**\n * Security scheme definitions.\n * Generated by `gkm openapi --ts`.\n */\n securitySchemes: SecuritySchemes;\n\n /**\n * Auth strategies for security schemes that are actually used.\n * Only schemes referenced in endpointAuth are required.\n *\n * @example\n * ```typescript\n * // If endpointAuth has: { 'GET /users': 'jwt', 'POST /data': 'iam', 'GET /public': null }\n * // Then authStrategies must include strategies for 'jwt' and 'iam'\n * authStrategies: {\n * jwt: { type: 'bearer', tokenProvider },\n * iam: { type: 'iam', signer: awsSigner },\n * }\n * ```\n */\n authStrategies: Record<UsedSecuritySchemes<EndpointAuth>, AuthStrategy>;\n\n /**\n * Optional request interceptor (runs after auth headers are added).\n */\n onRequest?: (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 Paths,\n EndpointAuth extends Record<string, string | null> = Record<\n string,\n string | null\n >,\n SecuritySchemes extends Record<string, SecuritySchemeObject> = Record<\n string,\n SecuritySchemeObject\n >,\n>(\n options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n baseURL: string;\n },\n): TypedApiFunction<Paths> {\n const {\n endpointAuth,\n securitySchemes,\n authStrategies,\n onRequest: userOnRequest,\n ...fetcherOptions\n } = options;\n\n // Create base fetcher with user's onRequest if provided\n const baseFetcher = new TypedFetcher<Paths>({\n ...fetcherOptions,\n onRequest: userOnRequest,\n });\n\n const fetcher = async <T extends TypedEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ): Promise<ExtractEndpointResponse<Paths, T>> => {\n // Look up auth requirement for this endpoint\n const schemeName = endpointAuth[endpoint as keyof EndpointAuth] as\n | string\n | null;\n\n let authHeaders: Record<string, string> = {};\n\n if (schemeName) {\n const scheme = securitySchemes[schemeName as keyof SecuritySchemes];\n // Since authStrategies is now required to have all used schemes,\n // we can safely access it - TypeScript ensures the strategy exists\n const strategy =\n authStrategies[schemeName as UsedSecuritySchemes<EndpointAuth>];\n\n if (strategy) {\n authHeaders = await resolveAuthHeaders(strategy, scheme);\n }\n }\n\n // Merge auth headers with config headers\n const existingHeaders =\n config && 'headers' in config && config.headers\n ? (config.headers as Record<string, string>)\n : {};\n\n const mergedConfig = {\n ...config,\n headers: {\n ...authHeaders,\n ...existingHeaders,\n },\n } as unknown as FilteredRequestConfig<Paths, T>;\n\n return baseFetcher.request(endpoint, mergedConfig);\n };\n\n return fetcher as TypedApiFunction<Paths>;\n}\n\n/**\n * Resolves auth headers based on the strategy and scheme.\n */\nasync function resolveAuthHeaders(\n strategy: AuthStrategy,\n scheme: SecuritySchemeObject,\n): Promise<Record<string, string>> {\n switch (strategy.type) {\n case 'bearer': {\n return strategy.tokenProvider.createValidAuthHeaders();\n }\n\n case 'apiKey': {\n const apiKey = await strategy.apiKeyProvider.getApiKey();\n const headerName = strategy.headerName || scheme.name || 'X-API-Key';\n\n if (scheme.in === 'header' || !scheme.in) {\n return { [headerName]: apiKey };\n }\n // Note: query and cookie API keys are handled differently\n // For now, we only support header-based API keys\n return {};\n }\n\n case 'iam': {\n // IAM signing requires the full URL and request config\n // This is a simplified version - full implementation would need\n // access to the complete request\n // For now, return empty - the actual signing should be done\n // in a custom onRequest interceptor if needed\n return {};\n }\n\n case 'none':\n default:\n return {};\n }\n}\n\n/**\n * Type helper to extract the security scheme ID from an endpoint.\n */\nexport type GetEndpointAuth<\n EndpointAuth extends Record<string, string | null>,\n Endpoint extends keyof EndpointAuth,\n> = EndpointAuth[Endpoint];\n\n/**\n * Type helper to get all authenticated endpoints.\n */\nexport type AuthenticatedEndpoints<\n EndpointAuth extends Record<string, string | null>,\n> = {\n [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 EndpointAuth extends Record<string, string | null>,\n> = {\n [K in keyof EndpointAuth]: EndpointAuth[K] extends null ? K : never;\n}[keyof EndpointAuth];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0JA,SAAgB,uBAWdA,SAGyB;CACzB,MAAM,EACJ,cACA,iBACA,gBACA,WAAW,cACX,GAAG,gBACJ,GAAG;CAGJ,MAAM,cAAc,IAAI,aAAoB;EAC1C,GAAG;EACH,WAAW;CACZ;CAED,MAAM,UAAU,OACdC,UACAC,WAC+C;EAE/C,MAAM,aAAa,aAAa;EAIhC,IAAIC,cAAsC,CAAE;AAE5C,MAAI,YAAY;GACd,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACJ,eAAe;AAEjB,OAAI,SACF,eAAc,MAAM,mBAAmB,UAAU,OAAO;EAE3D;EAGD,MAAM,kBACJ,UAAU,aAAa,UAAU,OAAO,UACnC,OAAO,UACR,CAAE;EAER,MAAM,eAAe;GACnB,GAAG;GACH,SAAS;IACP,GAAG;IACH,GAAG;GACJ;EACF;AAED,SAAO,YAAY,QAAQ,UAAU,aAAa;CACnD;AAED,QAAO;AACR;;;;AAKD,eAAe,mBACbC,UACAC,QACiC;AACjC,SAAQ,SAAS,MAAjB;EACE,KAAK,SACH,QAAO,SAAS,cAAc,wBAAwB;EAGxD,KAAK,UAAU;GACb,MAAM,SAAS,MAAM,SAAS,eAAe,WAAW;GACxD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;AAEzD,OAAI,OAAO,OAAO,aAAa,OAAO,GACpC,QAAO,GAAG,aAAa,OAAQ;AAIjC,UAAO,CAAE;EACV;EAED,KAAK,MAMH,QAAO,CAAE;EAGX,KAAK;EACL,QACE,QAAO,CAAE;CACZ;AACF"}
1
+ {"version":3,"file":"auth-fetcher.mjs","names":["options: AuthFetcherOptions<EndpointAuth, SecuritySchemes> & {\n\t\tbaseURL: string;\n\t}","endpoint: T","config?: FilteredRequestConfig<Paths, T>","authHeaders: Record<string, string>","strategy: AuthStrategy","scheme: SecuritySchemeObject"],"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,uBAWfA,SAG0B;CAC1B,MAAM,EACL,cACA,iBACA,gBACA,WAAW,cACX,GAAG,gBACH,GAAG;CAGJ,MAAM,cAAc,IAAI,aAAoB;EAC3C,GAAG;EACH,WAAW;CACX;CAED,MAAM,UAAU,OACfC,UACAC,WACgD;EAEhD,MAAM,aAAa,aAAa;EAIhC,IAAIC,cAAsC,CAAE;AAE5C,MAAI,YAAY;GACf,MAAM,SAAS,gBAAgB;GAG/B,MAAM,WACL,eAAe;AAEhB,OAAI,YAAY,OACf,eAAc,MAAM,mBAAmB,UAAU,OAAO;EAEzD;EAGD,MAAM,kBACL,UAAU,aAAa,UAAU,OAAO,UACpC,OAAO,UACR,CAAE;EAEN,MAAM,eAAe;GACpB,GAAG;GACH,SAAS;IACR,GAAG;IACH,GAAG;GACH;EACD;AAED,SAAO,YAAY,QAAQ,UAAU,aAAa;CAClD;AAED,QAAO;AACP;;;;AAKD,eAAe,mBACdC,UACAC,QACkC;AAClC,SAAQ,SAAS,MAAjB;EACC,KAAK,SACJ,QAAO,SAAS,cAAc,wBAAwB;EAGvD,KAAK,UAAU;GACd,MAAM,SAAS,MAAM,SAAS,eAAe,WAAW;GACxD,MAAM,aAAa,SAAS,cAAc,OAAO,QAAQ;AAEzD,OAAI,OAAO,OAAO,aAAa,OAAO,GACrC,QAAO,GAAG,aAAa,OAAQ;AAIhC,UAAO,CAAE;EACT;EAED,KAAK,MAMJ,QAAO,CAAE;EAEV,QACC,QAAO,CAAE;CACV;AACD"}
@@ -27,7 +27,7 @@ function buildQueryKey(endpoint, config) {
27
27
  * await mutation.mutateAsync({ body: { name: 'John' } });
28
28
  * ```
29
29
  */
30
- function createEndpointHooks(fetcher, options = {}) {
30
+ function createEndpointHooks(fetcher, _options = {}) {
31
31
  return {
32
32
  useQuery: (endpoint, ...args) => {
33
33
  const [config, queryOptions] = args;
@@ -37,10 +37,11 @@ function createEndpointHooks(fetcher, options = {}) {
37
37
  queryFn: () => fetcher(endpoint, config),
38
38
  ...queryOptions
39
39
  }), [
40
- queryKey.join(","),
41
40
  endpoint,
42
- JSON.stringify(config),
43
- JSON.stringify(queryOptions)
41
+ config,
42
+ fetcher,
43
+ queryKey,
44
+ queryOptions
44
45
  ]);
45
46
  return (0, __tanstack_react_query.useQuery)(memoizedOptions);
46
47
  },
@@ -48,7 +49,11 @@ function createEndpointHooks(fetcher, options = {}) {
48
49
  const memoizedOptions = (0, react.useMemo)(() => ({
49
50
  mutationFn: (config) => fetcher(endpoint, config),
50
51
  ...mutationOptions
51
- }), [endpoint, JSON.stringify(mutationOptions)]);
52
+ }), [
53
+ endpoint,
54
+ fetcher,
55
+ mutationOptions
56
+ ]);
52
57
  return (0, __tanstack_react_query.useMutation)(memoizedOptions);
53
58
  },
54
59
  buildQueryKey
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-hooks.cjs","names":["endpoint: T","config?: FilteredRequestConfig<Paths, T>","key: unknown[]","fetcher: TypedApiFunction<Paths>","options: CreateEndpointHooksOptions","mutationOptions?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >","config: FilteredRequestConfig<Paths, T>"],"sources":["../src/endpoint-hooks.ts"],"sourcesContent":["import type {\n QueryClient,\n UseMutationOptions,\n UseQueryOptions,\n} from '@tanstack/react-query';\nimport { useMutation, useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type {\n ExtractEndpointResponse,\n FilteredRequestConfig,\n IsConfigRequired,\n MutationEndpoint,\n QueryEndpoint,\n TypedApiFunction,\n} from './types';\n\n/**\n * Build query key from endpoint and config\n */\nfunction buildQueryKey<Paths, T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n): unknown[] {\n const key: unknown[] = [endpoint];\n\n if (config && 'params' in config && config.params) {\n key.push({ params: config.params });\n }\n\n if (config && 'query' in config && config.query) {\n key.push({ query: config.query });\n }\n\n return key;\n}\n\n/**\n * Options for creating endpoint-based hooks\n */\nexport interface CreateEndpointHooksOptions {\n queryClient?: QueryClient;\n}\n\n/**\n * Hook options type that conditionally requires config\n */\ntype UseQueryArgs<Paths, T extends QueryEndpoint<Paths>> = IsConfigRequired<\n Paths,\n T\n> extends true\n ? [\n config: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n 'queryKey' | 'queryFn'\n >,\n ]\n : [\n config?: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n 'queryKey' | 'queryFn'\n >,\n ];\n\n/**\n * Endpoint-based React Query hooks\n */\nexport interface EndpointHooks<Paths> {\n /**\n * Use query hook for GET endpoints.\n * Config is required when endpoint has path params.\n */\n useQuery: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n ...args: UseQueryArgs<Paths, T>\n ) => ReturnType<typeof useQuery<ExtractEndpointResponse<Paths, T>, Error>>;\n\n /**\n * Use mutation hook for POST, PUT, PATCH, DELETE endpoints.\n * Config with params/body is passed to mutate().\n */\n useMutation: <T extends MutationEndpoint<Paths>>(\n endpoint: T,\n options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n ) => ReturnType<\n typeof useMutation<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >\n >;\n\n /**\n * Build a query key for manual cache operations\n */\n buildQueryKey: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ) => unknown[];\n}\n\n/**\n * Create endpoint-based React Query hooks from a typed fetcher.\n *\n * @example\n * ```typescript\n * const fetcher = createAuthAwareFetcher<paths>({ ... });\n * const hooks = createEndpointHooks<paths>(fetcher);\n *\n * // In a component\n * const { data } = hooks.useQuery('GET /users/{id}', { params: { id: '123' } });\n *\n * const mutation = hooks.useMutation('POST /users');\n * await mutation.mutateAsync({ body: { name: 'John' } });\n * ```\n */\nexport function createEndpointHooks<Paths>(\n fetcher: TypedApiFunction<Paths>,\n options: CreateEndpointHooksOptions = {},\n): EndpointHooks<Paths> {\n return {\n useQuery: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n ...args: UseQueryArgs<Paths, T>\n ) => {\n // Parse args - config is first, options is second\n const [config, queryOptions] = args as [\n FilteredRequestConfig<Paths, T> | undefined,\n (\n | Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n 'queryKey' | 'queryFn'\n >\n | undefined\n ),\n ];\n\n const queryKey = buildQueryKey(endpoint, config);\n\n const memoizedOptions = useMemo(\n () => ({\n queryKey,\n queryFn: () =>\n fetcher(\n endpoint as Parameters<typeof fetcher>[0],\n config as Parameters<typeof fetcher>[1],\n ),\n ...queryOptions,\n }),\n [\n queryKey.join(','),\n endpoint,\n JSON.stringify(config),\n JSON.stringify(queryOptions),\n ],\n );\n\n return useQuery<ExtractEndpointResponse<Paths, T>, Error>(\n memoizedOptions,\n );\n },\n\n useMutation: <T extends MutationEndpoint<Paths>>(\n endpoint: T,\n mutationOptions?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n ) => {\n const memoizedOptions = useMemo(\n () => ({\n mutationFn: (config: FilteredRequestConfig<Paths, T>) =>\n fetcher(\n endpoint as Parameters<typeof fetcher>[0],\n config as Parameters<typeof fetcher>[1],\n ),\n ...mutationOptions,\n }),\n [endpoint, JSON.stringify(mutationOptions)],\n );\n\n return useMutation<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >(memoizedOptions);\n },\n\n buildQueryKey,\n };\n}\n"],"mappings":";;;;;;;;AAmBA,SAAS,cACPA,UACAC,QACW;CACX,MAAMC,MAAiB,CAAC,QAAS;AAEjC,KAAI,UAAU,YAAY,UAAU,OAAO,OACzC,KAAI,KAAK,EAAE,QAAQ,OAAO,OAAQ,EAAC;AAGrC,KAAI,UAAU,WAAW,UAAU,OAAO,MACxC,KAAI,KAAK,EAAE,OAAO,OAAO,MAAO,EAAC;AAGnC,QAAO;AACR;;;;;;;;;;;;;;;;AA0FD,SAAgB,oBACdC,SACAC,UAAsC,CAAE,GAClB;AACtB,QAAO;EACL,UAAU,CACRJ,UACA,GAAG,SACA;GAEH,MAAM,CAAC,QAAQ,aAAa,GAAG;GAW/B,MAAM,WAAW,cAAc,UAAU,OAAO;GAEhD,MAAM,kBAAkB,mBACtB,OAAO;IACL;IACA,SAAS,MACP,QACE,UACA,OACD;IACH,GAAG;GACJ,IACD;IACE,SAAS,KAAK,IAAI;IAClB;IACA,KAAK,UAAU,OAAO;IACtB,KAAK,UAAU,aAAa;GAC7B,EACF;AAED,UAAO,qCACL,gBACD;EACF;EAED,aAAa,CACXA,UACAK,oBAQG;GACH,MAAM,kBAAkB,mBACtB,OAAO;IACL,YAAY,CAACC,WACX,QACE,UACA,OACD;IACH,GAAG;GACJ,IACD,CAAC,UAAU,KAAK,UAAU,gBAAgB,AAAC,EAC5C;AAED,UAAO,wCAIL,gBAAgB;EACnB;EAED;CACD;AACF"}
1
+ {"version":3,"file":"endpoint-hooks.cjs","names":["endpoint: T","config?: FilteredRequestConfig<Paths, T>","key: unknown[]","fetcher: TypedApiFunction<Paths>","_options: CreateEndpointHooksOptions","mutationOptions?: Omit<\n\t\t\t\tUseMutationOptions<\n\t\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\t\tError,\n\t\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t\t>,\n\t\t\t\t'mutationFn'\n\t\t\t>","config: FilteredRequestConfig<Paths, T>"],"sources":["../src/endpoint-hooks.ts"],"sourcesContent":["import type {\n\tQueryClient,\n\tUseMutationOptions,\n\tUseQueryOptions,\n} from '@tanstack/react-query';\nimport { useMutation, useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type {\n\tExtractEndpointResponse,\n\tFilteredRequestConfig,\n\tIsConfigRequired,\n\tMutationEndpoint,\n\tQueryEndpoint,\n\tTypedApiFunction,\n} from './types';\n\n/**\n * Build query key from endpoint and config\n */\nfunction buildQueryKey<Paths, T extends QueryEndpoint<Paths>>(\n\tendpoint: T,\n\tconfig?: FilteredRequestConfig<Paths, T>,\n): unknown[] {\n\tconst key: unknown[] = [endpoint];\n\n\tif (config && 'params' in config && config.params) {\n\t\tkey.push({ params: config.params });\n\t}\n\n\tif (config && 'query' in config && config.query) {\n\t\tkey.push({ query: config.query });\n\t}\n\n\treturn key;\n}\n\n/**\n * Options for creating endpoint-based hooks\n */\nexport interface CreateEndpointHooksOptions {\n\tqueryClient?: QueryClient;\n}\n\n/**\n * Hook options type that conditionally requires config\n */\ntype UseQueryArgs<Paths, T extends QueryEndpoint<Paths>> = IsConfigRequired<\n\tPaths,\n\tT\n> extends true\n\t? [\n\t\t\tconfig: FilteredRequestConfig<Paths, T>,\n\t\t\toptions?: Omit<\n\t\t\t\tUseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n\t\t\t\t'queryKey' | 'queryFn'\n\t\t\t>,\n\t\t]\n\t: [\n\t\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t\t\toptions?: Omit<\n\t\t\t\tUseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n\t\t\t\t'queryKey' | 'queryFn'\n\t\t\t>,\n\t\t];\n\n/**\n * Endpoint-based React Query hooks\n */\nexport interface EndpointHooks<Paths> {\n\t/**\n\t * Use query hook for GET endpoints.\n\t * Config is required when endpoint has path params.\n\t */\n\tuseQuery: <T extends QueryEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\t...args: UseQueryArgs<Paths, T>\n\t) => ReturnType<typeof useQuery<ExtractEndpointResponse<Paths, T>, Error>>;\n\n\t/**\n\t * Use mutation hook for POST, PUT, PATCH, DELETE endpoints.\n\t * Config with params/body is passed to mutate().\n\t */\n\tuseMutation: <T extends MutationEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\toptions?: Omit<\n\t\t\tUseMutationOptions<\n\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\tError,\n\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t>,\n\t\t\t'mutationFn'\n\t\t>,\n\t) => ReturnType<\n\t\ttypeof useMutation<\n\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\tError,\n\t\t\tFilteredRequestConfig<Paths, T>\n\t\t>\n\t>;\n\n\t/**\n\t * Build a query key for manual cache operations\n\t */\n\tbuildQueryKey: <T extends QueryEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => unknown[];\n}\n\n/**\n * Create endpoint-based React Query hooks from a typed fetcher.\n *\n * @example\n * ```typescript\n * const fetcher = createAuthAwareFetcher<paths>({ ... });\n * const hooks = createEndpointHooks<paths>(fetcher);\n *\n * // In a component\n * const { data } = hooks.useQuery('GET /users/{id}', { params: { id: '123' } });\n *\n * const mutation = hooks.useMutation('POST /users');\n * await mutation.mutateAsync({ body: { name: 'John' } });\n * ```\n */\nexport function createEndpointHooks<Paths>(\n\tfetcher: TypedApiFunction<Paths>,\n\t_options: CreateEndpointHooksOptions = {},\n): EndpointHooks<Paths> {\n\treturn {\n\t\tuseQuery: <T extends QueryEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\t...args: UseQueryArgs<Paths, T>\n\t\t) => {\n\t\t\t// Parse args - config is first, options is second\n\t\t\tconst [config, queryOptions] = args as [\n\t\t\t\tFilteredRequestConfig<Paths, T> | undefined,\n\t\t\t\t(\n\t\t\t\t\t| Omit<\n\t\t\t\t\t\t\tUseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n\t\t\t\t\t\t\t'queryKey' | 'queryFn'\n\t\t\t\t\t >\n\t\t\t\t\t| undefined\n\t\t\t\t),\n\t\t\t];\n\n\t\t\tconst queryKey = buildQueryKey(endpoint, config);\n\n\t\t\tconst memoizedOptions = useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\tqueryKey,\n\t\t\t\t\tqueryFn: () =>\n\t\t\t\t\t\t// Type assertion needed due to complex conditional types\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tfetcher as (\n\t\t\t\t\t\t\t\tendpoint: T,\n\t\t\t\t\t\t\t\tconfig?: unknown,\n\t\t\t\t\t\t\t) => Promise<ExtractEndpointResponse<Paths, T>>\n\t\t\t\t\t\t)(endpoint, config),\n\t\t\t\t\t...queryOptions,\n\t\t\t\t}),\n\t\t\t\t[endpoint, config, fetcher, queryKey, queryOptions],\n\t\t\t);\n\n\t\t\treturn useQuery<ExtractEndpointResponse<Paths, T>, Error>(\n\t\t\t\tmemoizedOptions,\n\t\t\t);\n\t\t},\n\n\t\tuseMutation: <T extends MutationEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\tmutationOptions?: Omit<\n\t\t\t\tUseMutationOptions<\n\t\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\t\tError,\n\t\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t\t>,\n\t\t\t\t'mutationFn'\n\t\t\t>,\n\t\t) => {\n\t\t\tconst memoizedOptions = useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\tmutationFn: (config: FilteredRequestConfig<Paths, T>) =>\n\t\t\t\t\t\t// Type assertion needed due to complex conditional types\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tfetcher as (\n\t\t\t\t\t\t\t\tendpoint: T,\n\t\t\t\t\t\t\t\tconfig?: unknown,\n\t\t\t\t\t\t\t) => Promise<ExtractEndpointResponse<Paths, T>>\n\t\t\t\t\t\t)(endpoint, config),\n\t\t\t\t\t...mutationOptions,\n\t\t\t\t}),\n\t\t\t\t[endpoint, fetcher, mutationOptions],\n\t\t\t);\n\n\t\t\treturn useMutation<\n\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\tError,\n\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t>(memoizedOptions);\n\t\t},\n\n\t\tbuildQueryKey,\n\t};\n}\n"],"mappings":";;;;;;;;AAmBA,SAAS,cACRA,UACAC,QACY;CACZ,MAAMC,MAAiB,CAAC,QAAS;AAEjC,KAAI,UAAU,YAAY,UAAU,OAAO,OAC1C,KAAI,KAAK,EAAE,QAAQ,OAAO,OAAQ,EAAC;AAGpC,KAAI,UAAU,WAAW,UAAU,OAAO,MACzC,KAAI,KAAK,EAAE,OAAO,OAAO,MAAO,EAAC;AAGlC,QAAO;AACP;;;;;;;;;;;;;;;;AA0FD,SAAgB,oBACfC,SACAC,WAAuC,CAAE,GAClB;AACvB,QAAO;EACN,UAAU,CACTJ,UACA,GAAG,SACC;GAEJ,MAAM,CAAC,QAAQ,aAAa,GAAG;GAW/B,MAAM,WAAW,cAAc,UAAU,OAAO;GAEhD,MAAM,kBAAkB,mBACvB,OAAO;IACN;IACA,SAAS,MAER,AACC,QAIC,UAAU,OAAO;IACpB,GAAG;GACH,IACD;IAAC;IAAU;IAAQ;IAAS;IAAU;GAAa,EACnD;AAED,UAAO,qCACN,gBACA;EACD;EAED,aAAa,CACZA,UACAK,oBAQI;GACJ,MAAM,kBAAkB,mBACvB,OAAO;IACN,YAAY,CAACC,WAEZ,AACC,QAIC,UAAU,OAAO;IACpB,GAAG;GACH,IACD;IAAC;IAAU;IAAS;GAAgB,EACpC;AAED,UAAO,wCAIL,gBAAgB;EAClB;EAED;CACA;AACD"}
@@ -1,4 +1,4 @@
1
- import { ExtractEndpointResponse, FilteredRequestConfig, IsConfigRequired, MutationEndpoint, QueryEndpoint, TypedApiFunction } from "./types-D4OSWveN.cjs";
1
+ import { ExtractEndpointResponse, FilteredRequestConfig, IsConfigRequired, MutationEndpoint, QueryEndpoint, TypedApiFunction } from "./types-4K4N-Fl1.cjs";
2
2
  import { QueryClient, UseMutationOptions, UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query";
3
3
 
4
4
  //#region src/endpoint-hooks.d.ts
@@ -47,7 +47,7 @@ interface EndpointHooks<Paths> {
47
47
  * await mutation.mutateAsync({ body: { name: 'John' } });
48
48
  * ```
49
49
  */
50
- declare function createEndpointHooks<Paths>(fetcher: TypedApiFunction<Paths>, options?: CreateEndpointHooksOptions): EndpointHooks<Paths>;
50
+ declare function createEndpointHooks<Paths>(fetcher: TypedApiFunction<Paths>, _options?: CreateEndpointHooksOptions): EndpointHooks<Paths>;
51
51
  //#endregion
52
52
  export { CreateEndpointHooksOptions, EndpointHooks, createEndpointHooks };
53
53
  //# sourceMappingURL=endpoint-hooks.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint-hooks.d.cts","names":[],"sources":["../src/endpoint-hooks.ts"],"sourcesContent":[],"mappings":";;;;;;AAuCA;AAEC;AAKgB,UAPA,0BAAA,CAOA;EAAA,WAAgC,CAAA,EANlC,WAMkC;;;;;KAA5C,YAK4B,CAAA,KAAA,EAAA,UALE,aAKF,CALgB,KAKhB,CAAA,CAAA,GAL0B,gBAK1B,CAJhC,KAIgC,EAHhC,CAGgC,CAAA,SAAA,IAAA,GAAA,CAAK,MAAE,EAA7B,qBAA6B,CAAP,KAAO,EAAA,CAAA,CAAA,EAAC,OAA9B,GACE,IADF,CAEP,eAFO,CAES,uBAFT,CAEiC,KAFjC,EAEwC,CAFxC,CAAA,EAE4C,KAF5C,CAAA,EAAA,UAAA,GAAA,SAAA,CAAA,CAAqB,GAAA,CAEiB,MAAE,GAKvC,qBALuC,CAKjB,KALiB,EAKV,CALU,CAAA,EAAC,OAAhC,GAMP,IANO,CAOhB,eAPgB,CAOA,uBAPA,CAOwB,KAPxB,EAO+B,CAP/B,CAAA,EAOmC,KAPnC,CAAA,EAAA,UAAA,GAAA,SAAA,CAAA,CAAuB;;;;AAKF,UAUxB,aAVwB,CAAA,KAAA,CAAA,CAAA;EAAC;;;;EAEC,QAAY,EAAA,CAAA,UAajC,aAbiC,CAanB,KAbmB,CAAA,CAAA,CAAA,QAAA,EAc3C,CAd2C,EAAA,GAAA,IAAA,EAe5C,YAf4C,CAe/B,KAf+B,EAexB,CAfwB,CAAA,EAAA,GAgBjD,UAhBiD,CAAA,OAgB/B,QAhB+B,CAgBtB,uBAhBsB,CAgBE,KAhBF,EAgBS,CAhBT,CAAA,EAgBa,KAhBb,CAAA,CAAA;EAAK;;AAD3C;AASjB;EAA8B,WAAA,EAAA,CAAA,UAcL,gBAdK,CAcY,KAdZ,CAAA,CAAA,CAAA,QAAA,EAelB,CAfkB,EAAA,OAAA,CAAA,EAgBlB,IAhBkB,CAiB3B,kBAjB2B,CAkB1B,uBAlB0B,CAkBF,KAlBE,EAkBK,CAlBL,CAAA,EAmB1B,KAnB0B,EAoB1B,qBApB0B,CAoBJ,KApBI,EAoBG,CApBH,CAAA,CAAA,EAAA,YAAA,CAAA,EAAA,GAwBxB,UAxBwB,CAAA,OAyBrB,WAzBqB,CA0B3B,uBA1B2B,CA0BH,KA1BG,EA0BI,CA1BJ,CAAA,EA2B3B,KA3B2B,EA4B3B,qBA5B2B,CA4BL,KA5BK,EA4BE,CA5BF,CAAA,CAAA,CAAA;EAAA;;;EAMjB,aACW,EAAA,CAAA,UA4BG,aA5BH,CA4BiB,KA5BjB,CAAA,CAAA,CAAA,QAAA,EA6BZ,CA7BY,EAAA,MAAA,CAAA,EA8Bb,qBA9Ba,CA8BS,KA9BT,EA8BgB,CA9BhB,CAAA,EAAA,GAAA,OAAA,EAAA;;;;;;;;;;;;;;;;;AAaS,iBAoCjB,mBApCiB,CAAA,KAAA,CAAA,CAAA,OAAA,EAqCvB,gBArCuB,CAqCN,KArCM,CAAA,EAAA,QAAA,CAAA,EAsCtB,0BAtCsB,CAAA,EAuC9B,aAvC8B,CAuChB,KAvCgB,CAAA"}
@@ -1,4 +1,4 @@
1
- import { ExtractEndpointResponse, FilteredRequestConfig, IsConfigRequired, MutationEndpoint, QueryEndpoint, TypedApiFunction } from "./types-Cdv1XAWr.mjs";
1
+ import { ExtractEndpointResponse, FilteredRequestConfig, IsConfigRequired, MutationEndpoint, QueryEndpoint, TypedApiFunction } from "./types-hhkZWjQn.mjs";
2
2
  import { QueryClient, UseMutationOptions, UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query";
3
3
 
4
4
  //#region src/endpoint-hooks.d.ts
@@ -47,7 +47,7 @@ interface EndpointHooks<Paths> {
47
47
  * await mutation.mutateAsync({ body: { name: 'John' } });
48
48
  * ```
49
49
  */
50
- declare function createEndpointHooks<Paths>(fetcher: TypedApiFunction<Paths>, options?: CreateEndpointHooksOptions): EndpointHooks<Paths>;
50
+ declare function createEndpointHooks<Paths>(fetcher: TypedApiFunction<Paths>, _options?: CreateEndpointHooksOptions): EndpointHooks<Paths>;
51
51
  //#endregion
52
52
  export { CreateEndpointHooksOptions, EndpointHooks, createEndpointHooks };
53
53
  //# sourceMappingURL=endpoint-hooks.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint-hooks.d.mts","names":[],"sources":["../src/endpoint-hooks.ts"],"sourcesContent":[],"mappings":";;;;;;AAuCA;AAEC;AAKgB,UAPA,0BAAA,CAOA;EAAA,WAAgC,CAAA,EANlC,WAMkC;;;;;KAA5C,YAK4B,CAAA,KAAA,EAAA,UALE,aAKF,CALgB,KAKhB,CAAA,CAAA,GAL0B,gBAK1B,CAJhC,KAIgC,EAHhC,CAGgC,CAAA,SAAA,IAAA,GAAA,CAAK,MAAE,EAA7B,qBAA6B,CAAP,KAAO,EAAA,CAAA,CAAA,EAAC,OAA9B,GACE,IADF,CAEP,eAFO,CAES,uBAFT,CAEiC,KAFjC,EAEwC,CAFxC,CAAA,EAE4C,KAF5C,CAAA,EAAA,UAAA,GAAA,SAAA,CAAA,CAAqB,GAAA,CAEiB,MAAE,GAKvC,qBALuC,CAKjB,KALiB,EAKV,CALU,CAAA,EAAC,OAAhC,GAMP,IANO,CAOhB,eAPgB,CAOA,uBAPA,CAOwB,KAPxB,EAO+B,CAP/B,CAAA,EAOmC,KAPnC,CAAA,EAAA,UAAA,GAAA,SAAA,CAAA,CAAuB;;;;AAKF,UAUxB,aAVwB,CAAA,KAAA,CAAA,CAAA;EAAC;;;;EAEC,QAAY,EAAA,CAAA,UAajC,aAbiC,CAanB,KAbmB,CAAA,CAAA,CAAA,QAAA,EAc3C,CAd2C,EAAA,GAAA,IAAA,EAe5C,YAf4C,CAe/B,KAf+B,EAexB,CAfwB,CAAA,EAAA,GAgBjD,UAhBiD,CAAA,OAgB/B,QAhB+B,CAgBtB,uBAhBsB,CAgBE,KAhBF,EAgBS,CAhBT,CAAA,EAgBa,KAhBb,CAAA,CAAA;EAAK;;AAD3C;AASjB;EAA8B,WAAA,EAAA,CAAA,UAcL,gBAdK,CAcY,KAdZ,CAAA,CAAA,CAAA,QAAA,EAelB,CAfkB,EAAA,OAAA,CAAA,EAgBlB,IAhBkB,CAiB3B,kBAjB2B,CAkB1B,uBAlB0B,CAkBF,KAlBE,EAkBK,CAlBL,CAAA,EAmB1B,KAnB0B,EAoB1B,qBApB0B,CAoBJ,KApBI,EAoBG,CApBH,CAAA,CAAA,EAAA,YAAA,CAAA,EAAA,GAwBxB,UAxBwB,CAAA,OAyBrB,WAzBqB,CA0B3B,uBA1B2B,CA0BH,KA1BG,EA0BI,CA1BJ,CAAA,EA2B3B,KA3B2B,EA4B3B,qBA5B2B,CA4BL,KA5BK,EA4BE,CA5BF,CAAA,CAAA,CAAA;EAAA;;;EAMjB,aACW,EAAA,CAAA,UA4BG,aA5BH,CA4BiB,KA5BjB,CAAA,CAAA,CAAA,QAAA,EA6BZ,CA7BY,EAAA,MAAA,CAAA,EA8Bb,qBA9Ba,CA8BS,KA9BT,EA8BgB,CA9BhB,CAAA,EAAA,GAAA,OAAA,EAAA;;;;;;;;;;;;;;;;;AAaS,iBAoCjB,mBApCiB,CAAA,KAAA,CAAA,CAAA,OAAA,EAqCvB,gBArCuB,CAqCN,KArCM,CAAA,EAAA,QAAA,CAAA,EAsCtB,0BAtCsB,CAAA,EAuC9B,aAvC8B,CAuChB,KAvCgB,CAAA"}
@@ -26,7 +26,7 @@ function buildQueryKey(endpoint, config) {
26
26
  * await mutation.mutateAsync({ body: { name: 'John' } });
27
27
  * ```
28
28
  */
29
- function createEndpointHooks(fetcher, options = {}) {
29
+ function createEndpointHooks(fetcher, _options = {}) {
30
30
  return {
31
31
  useQuery: (endpoint, ...args) => {
32
32
  const [config, queryOptions] = args;
@@ -36,10 +36,11 @@ function createEndpointHooks(fetcher, options = {}) {
36
36
  queryFn: () => fetcher(endpoint, config),
37
37
  ...queryOptions
38
38
  }), [
39
- queryKey.join(","),
40
39
  endpoint,
41
- JSON.stringify(config),
42
- JSON.stringify(queryOptions)
40
+ config,
41
+ fetcher,
42
+ queryKey,
43
+ queryOptions
43
44
  ]);
44
45
  return useQuery(memoizedOptions);
45
46
  },
@@ -47,7 +48,11 @@ function createEndpointHooks(fetcher, options = {}) {
47
48
  const memoizedOptions = useMemo(() => ({
48
49
  mutationFn: (config) => fetcher(endpoint, config),
49
50
  ...mutationOptions
50
- }), [endpoint, JSON.stringify(mutationOptions)]);
51
+ }), [
52
+ endpoint,
53
+ fetcher,
54
+ mutationOptions
55
+ ]);
51
56
  return useMutation(memoizedOptions);
52
57
  },
53
58
  buildQueryKey
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-hooks.mjs","names":["endpoint: T","config?: FilteredRequestConfig<Paths, T>","key: unknown[]","fetcher: TypedApiFunction<Paths>","options: CreateEndpointHooksOptions","mutationOptions?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >","config: FilteredRequestConfig<Paths, T>"],"sources":["../src/endpoint-hooks.ts"],"sourcesContent":["import type {\n QueryClient,\n UseMutationOptions,\n UseQueryOptions,\n} from '@tanstack/react-query';\nimport { useMutation, useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type {\n ExtractEndpointResponse,\n FilteredRequestConfig,\n IsConfigRequired,\n MutationEndpoint,\n QueryEndpoint,\n TypedApiFunction,\n} from './types';\n\n/**\n * Build query key from endpoint and config\n */\nfunction buildQueryKey<Paths, T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n): unknown[] {\n const key: unknown[] = [endpoint];\n\n if (config && 'params' in config && config.params) {\n key.push({ params: config.params });\n }\n\n if (config && 'query' in config && config.query) {\n key.push({ query: config.query });\n }\n\n return key;\n}\n\n/**\n * Options for creating endpoint-based hooks\n */\nexport interface CreateEndpointHooksOptions {\n queryClient?: QueryClient;\n}\n\n/**\n * Hook options type that conditionally requires config\n */\ntype UseQueryArgs<Paths, T extends QueryEndpoint<Paths>> = IsConfigRequired<\n Paths,\n T\n> extends true\n ? [\n config: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n 'queryKey' | 'queryFn'\n >,\n ]\n : [\n config?: FilteredRequestConfig<Paths, T>,\n options?: Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n 'queryKey' | 'queryFn'\n >,\n ];\n\n/**\n * Endpoint-based React Query hooks\n */\nexport interface EndpointHooks<Paths> {\n /**\n * Use query hook for GET endpoints.\n * Config is required when endpoint has path params.\n */\n useQuery: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n ...args: UseQueryArgs<Paths, T>\n ) => ReturnType<typeof useQuery<ExtractEndpointResponse<Paths, T>, Error>>;\n\n /**\n * Use mutation hook for POST, PUT, PATCH, DELETE endpoints.\n * Config with params/body is passed to mutate().\n */\n useMutation: <T extends MutationEndpoint<Paths>>(\n endpoint: T,\n options?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n ) => ReturnType<\n typeof useMutation<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >\n >;\n\n /**\n * Build a query key for manual cache operations\n */\n buildQueryKey: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n config?: FilteredRequestConfig<Paths, T>,\n ) => unknown[];\n}\n\n/**\n * Create endpoint-based React Query hooks from a typed fetcher.\n *\n * @example\n * ```typescript\n * const fetcher = createAuthAwareFetcher<paths>({ ... });\n * const hooks = createEndpointHooks<paths>(fetcher);\n *\n * // In a component\n * const { data } = hooks.useQuery('GET /users/{id}', { params: { id: '123' } });\n *\n * const mutation = hooks.useMutation('POST /users');\n * await mutation.mutateAsync({ body: { name: 'John' } });\n * ```\n */\nexport function createEndpointHooks<Paths>(\n fetcher: TypedApiFunction<Paths>,\n options: CreateEndpointHooksOptions = {},\n): EndpointHooks<Paths> {\n return {\n useQuery: <T extends QueryEndpoint<Paths>>(\n endpoint: T,\n ...args: UseQueryArgs<Paths, T>\n ) => {\n // Parse args - config is first, options is second\n const [config, queryOptions] = args as [\n FilteredRequestConfig<Paths, T> | undefined,\n (\n | Omit<\n UseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n 'queryKey' | 'queryFn'\n >\n | undefined\n ),\n ];\n\n const queryKey = buildQueryKey(endpoint, config);\n\n const memoizedOptions = useMemo(\n () => ({\n queryKey,\n queryFn: () =>\n fetcher(\n endpoint as Parameters<typeof fetcher>[0],\n config as Parameters<typeof fetcher>[1],\n ),\n ...queryOptions,\n }),\n [\n queryKey.join(','),\n endpoint,\n JSON.stringify(config),\n JSON.stringify(queryOptions),\n ],\n );\n\n return useQuery<ExtractEndpointResponse<Paths, T>, Error>(\n memoizedOptions,\n );\n },\n\n useMutation: <T extends MutationEndpoint<Paths>>(\n endpoint: T,\n mutationOptions?: Omit<\n UseMutationOptions<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >,\n 'mutationFn'\n >,\n ) => {\n const memoizedOptions = useMemo(\n () => ({\n mutationFn: (config: FilteredRequestConfig<Paths, T>) =>\n fetcher(\n endpoint as Parameters<typeof fetcher>[0],\n config as Parameters<typeof fetcher>[1],\n ),\n ...mutationOptions,\n }),\n [endpoint, JSON.stringify(mutationOptions)],\n );\n\n return useMutation<\n ExtractEndpointResponse<Paths, T>,\n Error,\n FilteredRequestConfig<Paths, T>\n >(memoizedOptions);\n },\n\n buildQueryKey,\n };\n}\n"],"mappings":";;;;;;;AAmBA,SAAS,cACPA,UACAC,QACW;CACX,MAAMC,MAAiB,CAAC,QAAS;AAEjC,KAAI,UAAU,YAAY,UAAU,OAAO,OACzC,KAAI,KAAK,EAAE,QAAQ,OAAO,OAAQ,EAAC;AAGrC,KAAI,UAAU,WAAW,UAAU,OAAO,MACxC,KAAI,KAAK,EAAE,OAAO,OAAO,MAAO,EAAC;AAGnC,QAAO;AACR;;;;;;;;;;;;;;;;AA0FD,SAAgB,oBACdC,SACAC,UAAsC,CAAE,GAClB;AACtB,QAAO;EACL,UAAU,CACRJ,UACA,GAAG,SACA;GAEH,MAAM,CAAC,QAAQ,aAAa,GAAG;GAW/B,MAAM,WAAW,cAAc,UAAU,OAAO;GAEhD,MAAM,kBAAkB,QACtB,OAAO;IACL;IACA,SAAS,MACP,QACE,UACA,OACD;IACH,GAAG;GACJ,IACD;IACE,SAAS,KAAK,IAAI;IAClB;IACA,KAAK,UAAU,OAAO;IACtB,KAAK,UAAU,aAAa;GAC7B,EACF;AAED,UAAO,SACL,gBACD;EACF;EAED,aAAa,CACXA,UACAK,oBAQG;GACH,MAAM,kBAAkB,QACtB,OAAO;IACL,YAAY,CAACC,WACX,QACE,UACA,OACD;IACH,GAAG;GACJ,IACD,CAAC,UAAU,KAAK,UAAU,gBAAgB,AAAC,EAC5C;AAED,UAAO,YAIL,gBAAgB;EACnB;EAED;CACD;AACF"}
1
+ {"version":3,"file":"endpoint-hooks.mjs","names":["endpoint: T","config?: FilteredRequestConfig<Paths, T>","key: unknown[]","fetcher: TypedApiFunction<Paths>","_options: CreateEndpointHooksOptions","mutationOptions?: Omit<\n\t\t\t\tUseMutationOptions<\n\t\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\t\tError,\n\t\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t\t>,\n\t\t\t\t'mutationFn'\n\t\t\t>","config: FilteredRequestConfig<Paths, T>"],"sources":["../src/endpoint-hooks.ts"],"sourcesContent":["import type {\n\tQueryClient,\n\tUseMutationOptions,\n\tUseQueryOptions,\n} from '@tanstack/react-query';\nimport { useMutation, useQuery } from '@tanstack/react-query';\nimport { useMemo } from 'react';\nimport type {\n\tExtractEndpointResponse,\n\tFilteredRequestConfig,\n\tIsConfigRequired,\n\tMutationEndpoint,\n\tQueryEndpoint,\n\tTypedApiFunction,\n} from './types';\n\n/**\n * Build query key from endpoint and config\n */\nfunction buildQueryKey<Paths, T extends QueryEndpoint<Paths>>(\n\tendpoint: T,\n\tconfig?: FilteredRequestConfig<Paths, T>,\n): unknown[] {\n\tconst key: unknown[] = [endpoint];\n\n\tif (config && 'params' in config && config.params) {\n\t\tkey.push({ params: config.params });\n\t}\n\n\tif (config && 'query' in config && config.query) {\n\t\tkey.push({ query: config.query });\n\t}\n\n\treturn key;\n}\n\n/**\n * Options for creating endpoint-based hooks\n */\nexport interface CreateEndpointHooksOptions {\n\tqueryClient?: QueryClient;\n}\n\n/**\n * Hook options type that conditionally requires config\n */\ntype UseQueryArgs<Paths, T extends QueryEndpoint<Paths>> = IsConfigRequired<\n\tPaths,\n\tT\n> extends true\n\t? [\n\t\t\tconfig: FilteredRequestConfig<Paths, T>,\n\t\t\toptions?: Omit<\n\t\t\t\tUseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n\t\t\t\t'queryKey' | 'queryFn'\n\t\t\t>,\n\t\t]\n\t: [\n\t\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t\t\toptions?: Omit<\n\t\t\t\tUseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n\t\t\t\t'queryKey' | 'queryFn'\n\t\t\t>,\n\t\t];\n\n/**\n * Endpoint-based React Query hooks\n */\nexport interface EndpointHooks<Paths> {\n\t/**\n\t * Use query hook for GET endpoints.\n\t * Config is required when endpoint has path params.\n\t */\n\tuseQuery: <T extends QueryEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\t...args: UseQueryArgs<Paths, T>\n\t) => ReturnType<typeof useQuery<ExtractEndpointResponse<Paths, T>, Error>>;\n\n\t/**\n\t * Use mutation hook for POST, PUT, PATCH, DELETE endpoints.\n\t * Config with params/body is passed to mutate().\n\t */\n\tuseMutation: <T extends MutationEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\toptions?: Omit<\n\t\t\tUseMutationOptions<\n\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\tError,\n\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t>,\n\t\t\t'mutationFn'\n\t\t>,\n\t) => ReturnType<\n\t\ttypeof useMutation<\n\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\tError,\n\t\t\tFilteredRequestConfig<Paths, T>\n\t\t>\n\t>;\n\n\t/**\n\t * Build a query key for manual cache operations\n\t */\n\tbuildQueryKey: <T extends QueryEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => unknown[];\n}\n\n/**\n * Create endpoint-based React Query hooks from a typed fetcher.\n *\n * @example\n * ```typescript\n * const fetcher = createAuthAwareFetcher<paths>({ ... });\n * const hooks = createEndpointHooks<paths>(fetcher);\n *\n * // In a component\n * const { data } = hooks.useQuery('GET /users/{id}', { params: { id: '123' } });\n *\n * const mutation = hooks.useMutation('POST /users');\n * await mutation.mutateAsync({ body: { name: 'John' } });\n * ```\n */\nexport function createEndpointHooks<Paths>(\n\tfetcher: TypedApiFunction<Paths>,\n\t_options: CreateEndpointHooksOptions = {},\n): EndpointHooks<Paths> {\n\treturn {\n\t\tuseQuery: <T extends QueryEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\t...args: UseQueryArgs<Paths, T>\n\t\t) => {\n\t\t\t// Parse args - config is first, options is second\n\t\t\tconst [config, queryOptions] = args as [\n\t\t\t\tFilteredRequestConfig<Paths, T> | undefined,\n\t\t\t\t(\n\t\t\t\t\t| Omit<\n\t\t\t\t\t\t\tUseQueryOptions<ExtractEndpointResponse<Paths, T>, Error>,\n\t\t\t\t\t\t\t'queryKey' | 'queryFn'\n\t\t\t\t\t >\n\t\t\t\t\t| undefined\n\t\t\t\t),\n\t\t\t];\n\n\t\t\tconst queryKey = buildQueryKey(endpoint, config);\n\n\t\t\tconst memoizedOptions = useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\tqueryKey,\n\t\t\t\t\tqueryFn: () =>\n\t\t\t\t\t\t// Type assertion needed due to complex conditional types\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tfetcher as (\n\t\t\t\t\t\t\t\tendpoint: T,\n\t\t\t\t\t\t\t\tconfig?: unknown,\n\t\t\t\t\t\t\t) => Promise<ExtractEndpointResponse<Paths, T>>\n\t\t\t\t\t\t)(endpoint, config),\n\t\t\t\t\t...queryOptions,\n\t\t\t\t}),\n\t\t\t\t[endpoint, config, fetcher, queryKey, queryOptions],\n\t\t\t);\n\n\t\t\treturn useQuery<ExtractEndpointResponse<Paths, T>, Error>(\n\t\t\t\tmemoizedOptions,\n\t\t\t);\n\t\t},\n\n\t\tuseMutation: <T extends MutationEndpoint<Paths>>(\n\t\t\tendpoint: T,\n\t\t\tmutationOptions?: Omit<\n\t\t\t\tUseMutationOptions<\n\t\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\t\tError,\n\t\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t\t>,\n\t\t\t\t'mutationFn'\n\t\t\t>,\n\t\t) => {\n\t\t\tconst memoizedOptions = useMemo(\n\t\t\t\t() => ({\n\t\t\t\t\tmutationFn: (config: FilteredRequestConfig<Paths, T>) =>\n\t\t\t\t\t\t// Type assertion needed due to complex conditional types\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tfetcher as (\n\t\t\t\t\t\t\t\tendpoint: T,\n\t\t\t\t\t\t\t\tconfig?: unknown,\n\t\t\t\t\t\t\t) => Promise<ExtractEndpointResponse<Paths, T>>\n\t\t\t\t\t\t)(endpoint, config),\n\t\t\t\t\t...mutationOptions,\n\t\t\t\t}),\n\t\t\t\t[endpoint, fetcher, mutationOptions],\n\t\t\t);\n\n\t\t\treturn useMutation<\n\t\t\t\tExtractEndpointResponse<Paths, T>,\n\t\t\t\tError,\n\t\t\t\tFilteredRequestConfig<Paths, T>\n\t\t\t>(memoizedOptions);\n\t\t},\n\n\t\tbuildQueryKey,\n\t};\n}\n"],"mappings":";;;;;;;AAmBA,SAAS,cACRA,UACAC,QACY;CACZ,MAAMC,MAAiB,CAAC,QAAS;AAEjC,KAAI,UAAU,YAAY,UAAU,OAAO,OAC1C,KAAI,KAAK,EAAE,QAAQ,OAAO,OAAQ,EAAC;AAGpC,KAAI,UAAU,WAAW,UAAU,OAAO,MACzC,KAAI,KAAK,EAAE,OAAO,OAAO,MAAO,EAAC;AAGlC,QAAO;AACP;;;;;;;;;;;;;;;;AA0FD,SAAgB,oBACfC,SACAC,WAAuC,CAAE,GAClB;AACvB,QAAO;EACN,UAAU,CACTJ,UACA,GAAG,SACC;GAEJ,MAAM,CAAC,QAAQ,aAAa,GAAG;GAW/B,MAAM,WAAW,cAAc,UAAU,OAAO;GAEhD,MAAM,kBAAkB,QACvB,OAAO;IACN;IACA,SAAS,MAER,AACC,QAIC,UAAU,OAAO;IACpB,GAAG;GACH,IACD;IAAC;IAAU;IAAQ;IAAS;IAAU;GAAa,EACnD;AAED,UAAO,SACN,gBACA;EACD;EAED,aAAa,CACZA,UACAK,oBAQI;GACJ,MAAM,kBAAkB,QACvB,OAAO;IACN,YAAY,CAACC,WAEZ,AACC,QAIC,UAAU,OAAO;IACpB,GAAG;GACH,IACD;IAAC;IAAU;IAAS;GAAgB,EACpC;AAED,UAAO,YAIL,gBAAgB;EAClB;EAED;CACA;AACD"}
@@ -71,7 +71,7 @@ var TypedFetcher = class TypedFetcher {
71
71
  const [method, ...routeParts] = endpoint.split(" ");
72
72
  const route = routeParts.join(" ");
73
73
  return {
74
- method: method.toLowerCase(),
74
+ method: method?.toLowerCase() ?? "",
75
75
  route
76
76
  };
77
77
  }
@@ -83,4 +83,4 @@ function createTypedFetcher(options) {
83
83
 
84
84
  //#endregion
85
85
  export { TypedFetcher, createTypedFetcher };
86
- //# sourceMappingURL=fetcher-DLDD_7Sa.mjs.map
86
+ //# sourceMappingURL=fetcher-5fnBE7Dk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetcher-5fnBE7Dk.mjs","names":["fn?: FetchFn","options: FetcherOptions","endpoint: T","config?: FilteredRequestConfig<Paths, T>","prefix: string","value: unknown","requestConfig: RequestInit","options?: FetcherOptions"],"sources":["../src/fetcher.ts"],"sourcesContent":["import type {\n\tEndpointString,\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tParseEndpoint,\n\tTypedEndpoint,\n} from './types';\n\nexport type { FetcherOptions } 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 queryParams = new URLSearchParams();\n\n\t\t\t// Recursive function to handle nested objects and arrays\n\t\t\tconst appendQueryParam = (prefix: string, value: unknown) => {\n\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t// Handle arrays by appending multiple values with the same key\n\t\t\t\t\tvalue.forEach((item) => {\n\t\t\t\t\t\tqueryParams.append(prefix, String(item));\n\t\t\t\t\t});\n\t\t\t\t} else if (typeof value === 'object') {\n\t\t\t\t\t// For objects, recursively flatten into dot notation\n\t\t\t\t\tObject.entries(value as Record<string, unknown>).forEach(\n\t\t\t\t\t\t([subKey, subValue]) => {\n\t\t\t\t\t\t\tappendQueryParam(`${prefix}.${subKey}`, subValue);\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tqueryParams.append(prefix, String(value));\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Process all query parameters\n\t\t\tObject.entries(config.query as Record<string, unknown>).forEach(\n\t\t\t\t([key, value]) => {\n\t\t\t\t\tappendQueryParam(key, value);\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst queryString = queryParams.toString();\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\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\treturn <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => fetcher.request(endpoint, config);\n}\n\nexport type FetchFn = typeof fetch;\n"],"mappings":";AAWA,IAAa,eAAb,MAAa,aAAoB;CAChC,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,OAAO,WAAWA,IAAuB;AACxC,MAAI,GACH,QAAO;AAGR,aAAW,WAAW,sBAAsB,OAAO,UAAU,WAC5D,QAAO,OAAO,MAAM,KAAK,OAAO;AAGjC,aACQ,eAAe,sBACf,WAAW,UAAU,WAE5B,QAAO,WAAW,MAAM,KAAK,WAAW;AAGzC,QAAM,IAAI,MAAM;CAChB;CAED,YAAYC,UAA0B,CAAE,GAAE;AACzC,OAAK,UAAU,QAAQ,WAAW;AAClC,OAAK,iBAAiB,QAAQ,WAAW,CAAE;AAC3C,OAAK,UAAU;AACf,OAAK,UAAU,aAAa,WAAW,QAAQ,MAAM;CACrD;CAED,MAAM,QACLC,UACAC,QAC6C;EAC7C,MAAM,EAAE,QAAQ,OAAO,GAAG,KAAK,cAAc,SAAS;EAGtD,IAAI,MAAM;AACV,MAAI,UAAU,YAAY,UAAU,OAAO,OAC1C,QAAO,QAAQ,OAAO,OAAkC,CAAC,QACxD,CAAC,CAAC,KAAK,MAAM,KAAK;AACjB,SAAM,IAAI,SAAS,GAAG,IAAI,IAAI,mBAAmB,OAAO,MAAM,CAAC,CAAC;EAChE,EACD;AAIF,MAAI,UAAU,WAAW,UAAU,OAAO,OAAO;GAChD,MAAM,cAAc,IAAI;GAGxB,MAAM,mBAAmB,CAACC,QAAgBC,UAAmB;AAC5D,QAAI,oBAAuB,UAAU,KACpC;AAGD,QAAI,MAAM,QAAQ,MAAM,CAEvB,OAAM,QAAQ,CAAC,SAAS;AACvB,iBAAY,OAAO,QAAQ,OAAO,KAAK,CAAC;IACxC,EAAC;oBACe,UAAU,SAE3B,QAAO,QAAQ,MAAiC,CAAC,QAChD,CAAC,CAAC,QAAQ,SAAS,KAAK;AACvB,uBAAkB,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;IACjD,EACD;QAED,aAAY,OAAO,QAAQ,OAAO,MAAM,CAAC;GAE1C;AAGD,UAAO,QAAQ,OAAO,MAAiC,CAAC,QACvD,CAAC,CAAC,KAAK,MAAM,KAAK;AACjB,qBAAiB,KAAK,MAAM;GAC5B,EACD;GAED,MAAM,cAAc,YAAY,UAAU;AAC1C,OAAI,YACH,SAAQ,GAAG,YAAY;EAExB;EAGD,IAAIC,gBAA6B;GAChC,QAAQ,OAAO,aAAa;GAC5B,SAAS;IACR,GAAG,KAAK;IACR,GAAK,UAAU,aAAa,UAAU,OAAO,WAAY,CAAE;GAC3D;EACD;AAGD,MAAI,UAAU,UAAU,UAAU,OAAO,MAAM;AAC9C,iBAAc,OAAO,KAAK,UAAU,OAAO,KAAK;AAChD,iBAAc,UAAU;IACvB,GAAG,cAAc;IACjB,gBAAgB;GAChB;EACD;AAGD,MAAI,KAAK,QAAQ,UAChB,iBAAgB,MAAM,KAAK,QAAQ,UAAU,cAAc;AAG5D,MAAI;GAEH,IAAI,WAAW,MAAM,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,IAAI,GAAG,cAAc;AAGzE,OAAI,KAAK,QAAQ,WAChB,YAAW,MAAM,KAAK,QAAQ,WAAW,SAAS;AAInD,QAAK,SAAS,GACb,OAAM;AAIP,OACC,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,iBAAiB,KAAK,IAE3C;GAID,MAAM,OAAO,MAAM,SAAS,MAAM;AAClC,UAAO;EACP,SAAQ,OAAO;AAEf,OAAI,KAAK,QAAQ,QAEhB,OAAM,KAAK,QAAQ,QAAQ,MAAM;AAElC,SAAM;EACN;CACD;CAED,AAAQ,cACPJ,UACmB;EACnB,MAAM,CAAC,QAAQ,GAAG,WAAW,GAAG,SAAS,MAAM,IAAI;EACnD,MAAM,QAAQ,WAAW,KAAK,IAAI;AAClC,SAAO;GAAE,QAAQ,QAAQ,aAAa,IAAI;GAAI;EAAO;CACrD;AACD;AAED,SAAgB,mBAA0BK,SAA0B;CACnE,MAAM,UAAU,IAAI,aAAoB;AACxC,QAAO,CACNL,UACAC,WACI,QAAQ,QAAQ,UAAU,OAAO;AACtC"}
@@ -72,7 +72,7 @@ var TypedFetcher = class TypedFetcher {
72
72
  const [method, ...routeParts] = endpoint.split(" ");
73
73
  const route = routeParts.join(" ");
74
74
  return {
75
- method: method.toLowerCase(),
75
+ method: method?.toLowerCase() ?? "",
76
76
  route
77
77
  };
78
78
  }
@@ -95,4 +95,4 @@ Object.defineProperty(exports, 'createTypedFetcher', {
95
95
  return createTypedFetcher;
96
96
  }
97
97
  });
98
- //# sourceMappingURL=fetcher-KdwHgdAl.cjs.map
98
+ //# sourceMappingURL=fetcher-CgLEaIAC.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetcher-CgLEaIAC.cjs","names":["fn?: FetchFn","options: FetcherOptions","endpoint: T","config?: FilteredRequestConfig<Paths, T>","prefix: string","value: unknown","requestConfig: RequestInit","options?: FetcherOptions"],"sources":["../src/fetcher.ts"],"sourcesContent":["import type {\n\tEndpointString,\n\tExtractEndpointResponse,\n\tFetcherOptions,\n\tFilteredRequestConfig,\n\tParseEndpoint,\n\tTypedEndpoint,\n} from './types';\n\nexport type { FetcherOptions } 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 queryParams = new URLSearchParams();\n\n\t\t\t// Recursive function to handle nested objects and arrays\n\t\t\tconst appendQueryParam = (prefix: string, value: unknown) => {\n\t\t\t\tif (value === undefined || value === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t// Handle arrays by appending multiple values with the same key\n\t\t\t\t\tvalue.forEach((item) => {\n\t\t\t\t\t\tqueryParams.append(prefix, String(item));\n\t\t\t\t\t});\n\t\t\t\t} else if (typeof value === 'object') {\n\t\t\t\t\t// For objects, recursively flatten into dot notation\n\t\t\t\t\tObject.entries(value as Record<string, unknown>).forEach(\n\t\t\t\t\t\t([subKey, subValue]) => {\n\t\t\t\t\t\t\tappendQueryParam(`${prefix}.${subKey}`, subValue);\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tqueryParams.append(prefix, String(value));\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Process all query parameters\n\t\t\tObject.entries(config.query as Record<string, unknown>).forEach(\n\t\t\t\t([key, value]) => {\n\t\t\t\t\tappendQueryParam(key, value);\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst queryString = queryParams.toString();\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\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\treturn <T extends TypedEndpoint<Paths>>(\n\t\tendpoint: T,\n\t\tconfig?: FilteredRequestConfig<Paths, T>,\n\t) => fetcher.request(endpoint, config);\n}\n\nexport type FetchFn = typeof fetch;\n"],"mappings":";;AAWA,IAAa,eAAb,MAAa,aAAoB;CAChC,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,OAAO,WAAWA,IAAuB;AACxC,MAAI,GACH,QAAO;AAGR,aAAW,WAAW,sBAAsB,OAAO,UAAU,WAC5D,QAAO,OAAO,MAAM,KAAK,OAAO;AAGjC,aACQ,eAAe,sBACf,WAAW,UAAU,WAE5B,QAAO,WAAW,MAAM,KAAK,WAAW;AAGzC,QAAM,IAAI,MAAM;CAChB;CAED,YAAYC,UAA0B,CAAE,GAAE;AACzC,OAAK,UAAU,QAAQ,WAAW;AAClC,OAAK,iBAAiB,QAAQ,WAAW,CAAE;AAC3C,OAAK,UAAU;AACf,OAAK,UAAU,aAAa,WAAW,QAAQ,MAAM;CACrD;CAED,MAAM,QACLC,UACAC,QAC6C;EAC7C,MAAM,EAAE,QAAQ,OAAO,GAAG,KAAK,cAAc,SAAS;EAGtD,IAAI,MAAM;AACV,MAAI,UAAU,YAAY,UAAU,OAAO,OAC1C,QAAO,QAAQ,OAAO,OAAkC,CAAC,QACxD,CAAC,CAAC,KAAK,MAAM,KAAK;AACjB,SAAM,IAAI,SAAS,GAAG,IAAI,IAAI,mBAAmB,OAAO,MAAM,CAAC,CAAC;EAChE,EACD;AAIF,MAAI,UAAU,WAAW,UAAU,OAAO,OAAO;GAChD,MAAM,cAAc,IAAI;GAGxB,MAAM,mBAAmB,CAACC,QAAgBC,UAAmB;AAC5D,QAAI,oBAAuB,UAAU,KACpC;AAGD,QAAI,MAAM,QAAQ,MAAM,CAEvB,OAAM,QAAQ,CAAC,SAAS;AACvB,iBAAY,OAAO,QAAQ,OAAO,KAAK,CAAC;IACxC,EAAC;oBACe,UAAU,SAE3B,QAAO,QAAQ,MAAiC,CAAC,QAChD,CAAC,CAAC,QAAQ,SAAS,KAAK;AACvB,uBAAkB,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;IACjD,EACD;QAED,aAAY,OAAO,QAAQ,OAAO,MAAM,CAAC;GAE1C;AAGD,UAAO,QAAQ,OAAO,MAAiC,CAAC,QACvD,CAAC,CAAC,KAAK,MAAM,KAAK;AACjB,qBAAiB,KAAK,MAAM;GAC5B,EACD;GAED,MAAM,cAAc,YAAY,UAAU;AAC1C,OAAI,YACH,SAAQ,GAAG,YAAY;EAExB;EAGD,IAAIC,gBAA6B;GAChC,QAAQ,OAAO,aAAa;GAC5B,SAAS;IACR,GAAG,KAAK;IACR,GAAK,UAAU,aAAa,UAAU,OAAO,WAAY,CAAE;GAC3D;EACD;AAGD,MAAI,UAAU,UAAU,UAAU,OAAO,MAAM;AAC9C,iBAAc,OAAO,KAAK,UAAU,OAAO,KAAK;AAChD,iBAAc,UAAU;IACvB,GAAG,cAAc;IACjB,gBAAgB;GAChB;EACD;AAGD,MAAI,KAAK,QAAQ,UAChB,iBAAgB,MAAM,KAAK,QAAQ,UAAU,cAAc;AAG5D,MAAI;GAEH,IAAI,WAAW,MAAM,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,IAAI,GAAG,cAAc;AAGzE,OAAI,KAAK,QAAQ,WAChB,YAAW,MAAM,KAAK,QAAQ,WAAW,SAAS;AAInD,QAAK,SAAS,GACb,OAAM;AAIP,OACC,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,iBAAiB,KAAK,IAE3C;GAID,MAAM,OAAO,MAAM,SAAS,MAAM;AAClC,UAAO;EACP,SAAQ,OAAO;AAEf,OAAI,KAAK,QAAQ,QAEhB,OAAM,KAAK,QAAQ,QAAQ,MAAM;AAElC,SAAM;EACN;CACD;CAED,AAAQ,cACPJ,UACmB;EACnB,MAAM,CAAC,QAAQ,GAAG,WAAW,GAAG,SAAS,MAAM,IAAI;EACnD,MAAM,QAAQ,WAAW,KAAK,IAAI;AAClC,SAAO;GAAE,QAAQ,QAAQ,aAAa,IAAI;GAAI;EAAO;CACrD;AACD;AAED,SAAgB,mBAA0BK,SAA0B;CACnE,MAAM,UAAU,IAAI,aAAoB;AACxC,QAAO,CACNL,UACAC,WACI,QAAQ,QAAQ,UAAU,OAAO;AACtC"}
package/dist/fetcher.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_fetcher = require('./fetcher-KdwHgdAl.cjs');
1
+ const require_fetcher = require('./fetcher-CgLEaIAC.cjs');
2
2
 
3
3
  exports.TypedFetcher = require_fetcher.TypedFetcher;
4
4
  exports.createTypedFetcher = require_fetcher.createTypedFetcher;
@@ -1,4 +1,4 @@
1
- import { ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, TypedEndpoint } from "./types-D4OSWveN.cjs";
1
+ import { ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, TypedEndpoint } from "./types-4K4N-Fl1.cjs";
2
2
 
3
3
  //#region src/fetcher.d.ts
4
4
  declare class TypedFetcher<Paths> {
@@ -13,6 +13,8 @@ declare class TypedFetcher<Paths> {
13
13
  }
14
14
  declare function createTypedFetcher<Paths>(options?: FetcherOptions): <T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>;
15
15
  type FetchFn = typeof fetch;
16
+ //# sourceMappingURL=fetcher.d.ts.map
17
+
16
18
  //#endregion
17
19
  export { FetchFn, FetcherOptions, TypedFetcher, createTypedFetcher };
18
20
  //# sourceMappingURL=fetcher.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetcher.d.cts","names":[],"sources":["../src/fetcher.ts"],"sourcesContent":[],"mappings":";;;cAWa;EAAA,QAAA,OAAY;EAAA,QAAA,cAAA;EAAA,QAMD,OAAA;EAAO,QAAG,OAAA;EAAO,OAmBnB,UAAA,CAAA,EAAA,CAAA,EAnBE,OAmBF,CAAA,EAnBY,OAmBZ;EAAmB,WAOF,CAAA,OAAA,CAAA,EAPjB,cAOiB;EAAK,OAAnB,CAAA,UAAA,aAAA,CAAc,KAAd,CAAA,CAAA,CAAA,QAAA,EACb,CADa,EAAA,MAAA,CAAA,EAEd,qBAFc,CAEQ,KAFR,EAEe,CAFf,CAAA,CAAA,EAGrB,OAHqB,CAGb,uBAHa,CAGW,KAHX,EAGkB,CAHlB,CAAA,CAAA;EAAa,QAC1B,aAAA;;AAC4B,iBAyHxB,kBAzHwB,CAAA,KAAA,CAAA,CAAA,OAAA,CAAA,EAyHY,cAzHZ,CAAA,EAAA,CAAA,UA2HrB,aA3HqB,CA2HP,KA3HO,CAAA,CAAA,CAAA,QAAA,EA4H5B,CA5H4B,EAAA,MAAA,CAAA,EA6H7B,qBA7H6B,CA6HP,KA7HO,EA6HA,CA7HA,CAAA,EAAA,GA6HE,OA7HF,CA6HE,uBA7HF,CA6HE,KA7HF,EA6HE,CA7HF,CAAA,CAAA;AAA7B,KAiIC,OAAA,GAjID,OAiIkB,KAjIlB"}
@@ -1,4 +1,4 @@
1
- import { ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, TypedEndpoint } from "./types-Cdv1XAWr.mjs";
1
+ import { ExtractEndpointResponse, FetcherOptions, FilteredRequestConfig, TypedEndpoint } from "./types-hhkZWjQn.mjs";
2
2
 
3
3
  //#region src/fetcher.d.ts
4
4
  declare class TypedFetcher<Paths> {
@@ -13,6 +13,8 @@ declare class TypedFetcher<Paths> {
13
13
  }
14
14
  declare function createTypedFetcher<Paths>(options?: FetcherOptions): <T extends TypedEndpoint<Paths>>(endpoint: T, config?: FilteredRequestConfig<Paths, T>) => Promise<ExtractEndpointResponse<Paths, T>>;
15
15
  type FetchFn = typeof fetch;
16
+ //# sourceMappingURL=fetcher.d.ts.map
17
+
16
18
  //#endregion
17
19
  export { FetchFn, FetcherOptions, TypedFetcher, createTypedFetcher };
18
20
  //# sourceMappingURL=fetcher.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetcher.d.mts","names":[],"sources":["../src/fetcher.ts"],"sourcesContent":[],"mappings":";;;cAWa;EAAA,QAAA,OAAY;EAAA,QAAA,cAAA;EAAA,QAMD,OAAA;EAAO,QAAG,OAAA;EAAO,OAmBnB,UAAA,CAAA,EAAA,CAAA,EAnBE,OAmBF,CAAA,EAnBY,OAmBZ;EAAmB,WAOF,CAAA,OAAA,CAAA,EAPjB,cAOiB;EAAK,OAAnB,CAAA,UAAA,aAAA,CAAc,KAAd,CAAA,CAAA,CAAA,QAAA,EACb,CADa,EAAA,MAAA,CAAA,EAEd,qBAFc,CAEQ,KAFR,EAEe,CAFf,CAAA,CAAA,EAGrB,OAHqB,CAGb,uBAHa,CAGW,KAHX,EAGkB,CAHlB,CAAA,CAAA;EAAa,QAC1B,aAAA;;AAC4B,iBAyHxB,kBAzHwB,CAAA,KAAA,CAAA,CAAA,OAAA,CAAA,EAyHY,cAzHZ,CAAA,EAAA,CAAA,UA2HrB,aA3HqB,CA2HP,KA3HO,CAAA,CAAA,CAAA,QAAA,EA4H5B,CA5H4B,EAAA,MAAA,CAAA,EA6H7B,qBA7H6B,CA6HP,KA7HO,EA6HA,CA7HA,CAAA,EAAA,GA6HE,OA7HF,CA6HE,uBA7HF,CA6HE,KA7HF,EA6HE,CA7HF,CAAA,CAAA;AAA7B,KAiIC,OAAA,GAjID,OAiIkB,KAjIlB"}
package/dist/fetcher.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { TypedFetcher, createTypedFetcher } from "./fetcher-DLDD_7Sa.mjs";
1
+ import { TypedFetcher, createTypedFetcher } from "./fetcher-5fnBE7Dk.mjs";
2
2
 
3
3
  export { TypedFetcher, createTypedFetcher };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infer.d.cts","names":[],"sources":["../src/infer.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAM8D;;KAMzD,eACJ,CAAA,eAAA,MAAA,CAAA,GAAA,MAAA,SAAA,GAAA,MAAA,IAAA,KAAA,MAAA,IAAA,KAAA,KAAA,EAAA,GAAA,QACW,KAAA,GAAA,MAAA,EAAK,GAAc,eAAgB,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA;;AAAD;AAAA;KAMzC,eAAe,CAAA,UAAW,UAAX,CAAA,GAAyB,SAAzB,CAAmC,CAAnC,CAAA;;;;AAAkC,KAKjD,oBALiD,CAAA,eAAA,MAAA,CAAA,GAMrD,eANqD,CAMrC,MANqC,CAAA,SAMrB,MANqB,CAAA,MAAA,EAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA;EAKjD,UAAA,EAAA;IAAoB,IAAA,EAKd,eALc,CAKE,MALF,CAAA;EAAA,CAAA;CACF;;;;AAIG,KAOrB,wBAPqB,CAAA,eAOmB,eAPnB,CAAA,GAOsC,MAPtC,SAAA;EAOrB,KAAA,EAAA,KAAA,EAAA;CAAwB,GAAA;EAAA,UAAgB,EAAA;IAAmB,KAAA,EAKrD,mBALqD,CAKjC,CALiC,CAAA;EAAM,CAAA;CAKtC,GAAA,CAAA,CAAA;AAAF;AAAA;;KAQzB,cACW,CAAA,eAAA,eAAA,EAAA,gBACC,gBADD,GAAA,SAAA,CAAA,GAEZ,wBAFY,CAEa,MAFb,CAAA,GAAA;EAAe,WACd,CAAA,EAEF,MAFE,SAAA;IACY,IAAA,EAAA,KAAA,EAAA;EAAM,CAAA,GAA/B;IACW,OAAA,EAAA;MAG8B,kBAAA,EAApB,mBAAoB,CAAA,CAAA,CAAA;IAApB,CAAA;EAAmB,CAAA,GAMhC,KAAA;EAAO,SAAS,EAAA;IAEkB,GAAA,EAAA;MAApB,OAAA,EAFd,OAEc,SAFE,gBAEF,GAAA;QAAmB,kBAAA,EAAnB,mBAAmB,CAAC,OAAD,CAAA;MA+BjC,CAAA,GAAA,KAAA;IAAwB,CAAA;EAAA,CAAA;CAClC;;;;;;;;;AAYmD;AA2CrD;;;;;;;;;;;;;;AAQiB;KAhEL,8BACX,UAAU;iBAWA,SAAS,qBAAqB,kBAC7B,gBAAgB,WAAW,eAAe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2ClD,kDACX,2DACG,yBAAyB;;IACxB;SACU;IACT,aAAa;;;SACH,KAAK;;SACL;IACX,aAAa"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infer.d.mts","names":[],"sources":["../src/infer.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAM8D;;KAMzD,eACJ,CAAA,eAAA,MAAA,CAAA,GAAA,MAAA,SAAA,GAAA,MAAA,IAAA,KAAA,MAAA,IAAA,KAAA,KAAA,EAAA,GAAA,QACW,KAAA,GAAA,MAAA,EAAK,GAAc,eAAgB,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA;;AAAD;AAAA;KAMzC,eAAe,CAAA,UAAW,UAAX,CAAA,GAAyB,SAAzB,CAAmC,CAAnC,CAAA;;;;AAAkC,KAKjD,oBALiD,CAAA,eAAA,MAAA,CAAA,GAMrD,eANqD,CAMrC,MANqC,CAAA,SAMrB,MANqB,CAAA,MAAA,EAAA,KAAA,CAAA,GAAA,CAAA,CAAA,GAAA;EAKjD,UAAA,EAAA;IAAoB,IAAA,EAKd,eALc,CAKE,MALF,CAAA;EAAA,CAAA;CACF;;;;AAIG,KAOrB,wBAPqB,CAAA,eAOmB,eAPnB,CAAA,GAOsC,MAPtC,SAAA;EAOrB,KAAA,EAAA,KAAA,EAAA;CAAwB,GAAA;EAAA,UAAgB,EAAA;IAAmB,KAAA,EAKrD,mBALqD,CAKjC,CALiC,CAAA;EAAM,CAAA;CAKtC,GAAA,CAAA,CAAA;AAAF;AAAA;;KAQzB,cACW,CAAA,eAAA,eAAA,EAAA,gBACC,gBADD,GAAA,SAAA,CAAA,GAEZ,wBAFY,CAEa,MAFb,CAAA,GAAA;EAAe,WACd,CAAA,EAEF,MAFE,SAAA;IACY,IAAA,EAAA,KAAA,EAAA;EAAM,CAAA,GAA/B;IACW,OAAA,EAAA;MAG8B,kBAAA,EAApB,mBAAoB,CAAA,CAAA,CAAA;IAApB,CAAA;EAAmB,CAAA,GAMhC,KAAA;EAAO,SAAS,EAAA;IAEkB,GAAA,EAAA;MAApB,OAAA,EAFd,OAEc,SAFE,gBAEF,GAAA;QAAmB,kBAAA,EAAnB,mBAAmB,CAAC,OAAD,CAAA;MA+BjC,CAAA,GAAA,KAAA;IAAwB,CAAA;EAAA,CAAA;CAClC;;;;;;;;;AAYmD;AA2CrD;;;;;;;;;;;;;;AAQiB;KAhEL,8BACX,UAAU;iBAWA,SAAS,qBAAqB,kBAC7B,gBAAgB,WAAW,eAAe,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2ClD,kDACX,2DACG,yBAAyB;;IACxB;SACU;IACT,aAAa;;;SACH,KAAK;;SACL;IACX,aAAa"}
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require('./chunk-CUT6urMc.cjs');
2
- const require_fetcher = require('./fetcher-KdwHgdAl.cjs');
2
+ const require_fetcher = require('./fetcher-CgLEaIAC.cjs');
3
3
  const __tanstack_react_query = require_chunk.__toESM(require("@tanstack/react-query"));
4
4
 
5
5
  //#region src/openapi-hooks.ts
@@ -7,10 +7,8 @@ function createOpenAPIHooks(options = {}) {
7
7
  const { operations,...fetcherOptions } = options;
8
8
  const fetcher = require_fetcher.createTypedFetcher(fetcherOptions);
9
9
  function buildEndpoint(operationId) {
10
- if (operations && operations[operationId]) {
11
- const op = operations[operationId];
12
- return `${op.method.toUpperCase()} ${op.path}`;
13
- }
10
+ const op = operations?.[operationId];
11
+ if (op) return `${op.method.toUpperCase()} ${op.path}`;
14
12
  return operationId;
15
13
  }
16
14
  return {