File tree Expand file tree Collapse file tree 3 files changed +100
-2
lines changed
Expand file tree Collapse file tree 3 files changed +100
-2
lines changed Original file line number Diff line number Diff line change @@ -473,6 +473,20 @@ export interface ClientOptions {
473473 globalParams ?: ClientRequestParams ;
474474}
475475
476+ type ServerVariableType < TVarName extends string , TVariables > =
477+ TVariables extends Record < string , unknown >
478+ ? TVarName extends keyof TVariables
479+ ? TVariables [ TVarName ] extends { enum : readonly ( infer TEnum extends string ) [ ] }
480+ ? TEnum
481+ : string
482+ : string
483+ : string ;
484+
485+ type ResolveServerUrl < TUrl extends string , TVariables > =
486+ TUrl extends `${infer Before } {${infer VarName } }${infer After } `
487+ ? `${Before } ${ServerVariableType < VarName , TVariables > } ${ResolveServerUrl < After , TVariables > } `
488+ : TUrl ;
489+
476490export type ClientOptionsWithStrictEndpoint < TOAS extends OpenAPIDocument > = Omit <
477491 ClientOptions ,
478492 'endpoint'
@@ -489,15 +503,15 @@ export type ClientOptionsWithStrictEndpoint<TOAS extends OpenAPIDocument> = Omit
489503 endpoint : TEndpoint ;
490504 }
491505 : TOAS extends {
492- servers : { url : infer TEndpoint extends string } [ ] ;
506+ servers : { url : infer TEndpoint extends string ; variables ?: infer TVariables } [ ] ;
493507 }
494508 ? {
495509 /**
496510 * The base URL of the API defined in the OAS document.
497511 *
498512 * @see https://swagger.io/docs/specification/api-host-and-base-path/
499513 */
500- endpoint : TEndpoint ;
514+ endpoint : ResolveServerUrl < TEndpoint , TVariables > ;
501515 }
502516 : TOAS extends {
503517 host : infer THost extends string ;
Original file line number Diff line number Diff line change 1+ export default {
2+ openapi : '3.0.0' ,
3+ info : {
4+ title : 'Server Variables Test API' ,
5+ version : '1.0.0' ,
6+ } ,
7+ servers : [
8+ {
9+ url : 'https://{username}.server.com:{port}/{version}' ,
10+ variables : {
11+ username : {
12+ default : 'demo' ,
13+ description : 'This value is assigned by the service provider.' ,
14+ } ,
15+ port : {
16+ enum : [ '8443' , '443' ] ,
17+ default : '8443' ,
18+ } ,
19+ version : {
20+ default : 'v1' ,
21+ } ,
22+ } ,
23+ } ,
24+ ] ,
25+ paths : {
26+ '/users' : {
27+ get : {
28+ operationId : 'getUsers' ,
29+ responses : {
30+ 200 : {
31+ description : 'A list of users' ,
32+ content : {
33+ 'application/json' : {
34+ schema : {
35+ type : 'array' ,
36+ items : {
37+ type : 'object' ,
38+ properties : {
39+ id : { type : 'string' } ,
40+ name : { type : 'string' } ,
41+ } ,
42+ } ,
43+ } ,
44+ } ,
45+ } ,
46+ } ,
47+ } ,
48+ } ,
49+ } ,
50+ } ,
51+ } as const ;
Original file line number Diff line number Diff line change 1+ import { createClient , type NormalizeOAS } from 'fets' ;
2+ import type { ClientOptionsWithStrictEndpoint } from '../../src/client/types' ;
3+ import serverVariablesOas from './fixtures/example-server-variables-oas' ;
4+
5+ type NormOAS = NormalizeOAS < typeof serverVariablesOas > ;
6+
7+ // Valid endpoint matching the server variable template (port from enum, username/version are strings)
8+ const client = createClient < NormOAS > ( {
9+ endpoint : 'https://me.server.com:443/v1' ,
10+ } ) ;
11+
12+ // Port from enum: '8443' also valid
13+ const client2 = createClient < NormOAS > ( {
14+ endpoint : 'https://demo.server.com:8443/v2' ,
15+ } ) ;
16+
17+ void client ;
18+ void client2 ;
19+
20+ // Verify the endpoint type is properly inferred via ClientOptionsWithStrictEndpoint
21+ // Port '444' is not in the enum ['8443', '443'] - this should be a type error
22+ const _invalidOpts : ClientOptionsWithStrictEndpoint < NormOAS > = {
23+ // @ts -expect-error - port '444' is not in the enum ['8443', '443']
24+ endpoint : 'https://me.server.com:444/v1' ,
25+ } ;
26+ void _invalidOpts ;
27+
28+ const getUsersRes = await client [ '/users' ] . get ( ) ;
29+
30+ if ( getUsersRes . ok ) {
31+ const users = await getUsersRes . json ( ) ;
32+ void users [ 0 ] ?. id ;
33+ }
You can’t perform that action at this time.
0 commit comments