@@ -8,10 +8,14 @@ import { Agent as HttpsAgent } from 'https';
88import fetch , { Response as FetchResponse } from 'node-fetch' ;
99import qs from 'query-string' ;
1010
11- // Represents HTTP methods supported by the API
11+ /**
12+ * @description HTTP methods supported by the API
13+ */
1214export type RequestMethod = 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT' ;
1315
14- // Represents a complete API request with its endpoint and parameters
16+ /**
17+ * @description Represents a complete API request with its endpoint and parameters
18+ */
1519export type Request <
1620 ReqLine extends RequestLine = RequestLine ,
1721 Params extends Parameters = Parameters ,
@@ -20,23 +24,37 @@ export type Request<
2024 readonly parameters : Params ;
2125} ;
2226
23- // Represents an API endpoint in the format "METHOD /path"
24- // e.g., "GET /products" or "POST /orders"
27+ /**
28+ * @description Represents an API endpoint in the format "METHOD /path"
29+ * e.g., "GET /products" or "POST /orders"
30+ */
2531export type RequestLine = `${RequestMethod } ${string } `;
2632
27- // Represents all possible parameter types that can be sent with a request:
28- // - path: URL path parameters (e.g., /products/{id})
29- // - query: URL query parameters
30- // - body: Request body data
31- // - header: Custom HTTP headers
33+ /**
34+ * @description Represents all possible parameter types that can be sent with a request:
35+ */
3236export type Parameters = {
37+ /**
38+ * @description URL path parameters (e.g., /products/{id})
39+ */
3340 readonly path ?: Record < string , any > ;
41+ /**
42+ * @description URL query parameters
43+ */
3444 readonly query ?: any ;
45+ /**
46+ * @description Request body data
47+ */
3548 readonly body ?: any ;
49+ /**
50+ * @description Custom HTTP headers
51+ */
3652 readonly header ?: Record < string , any > ;
3753} ;
3854
39- // Represents an API response with status code and optional body
55+ /**
56+ * @description Represents an API response with status code and optional body
57+ */
4058export type Response = {
4159 readonly status : number | string ;
4260 readonly body ?: any ;
@@ -45,14 +63,20 @@ export type Response = {
4563// Namespace for response-related type utilities
4664export namespace Response {
4765 type SuccessStatus = 200 | 201 | 204 ;
66+
67+ /**
68+ * @description Extracts and formats the possible success responses for an operation
69+ */
4870 export type Success < T extends Response | Operation > = T extends Operation
4971 ? Success < T [ 'response' ] >
5072 : T extends { status : SuccessStatus }
5173 ? T
5274 : never ;
5375}
5476
55- // Represents a complete API operation with its parameters and expected response
77+ /**
78+ * @description Represents a complete API operation with its parameters and expected response
79+ */
5680export type Operation = {
5781 readonly parameters : Request [ 'parameters' ] ;
5882 readonly response : Response ;
@@ -61,43 +85,59 @@ export type Operation = {
6185// Namespace for operation-related type utilities
6286// TODO: MI-199 - determine if this is still required
6387export namespace Operation {
64- // Extracts the minimal required input parameters for an operation
88+ /**
89+ * @description Extracts the minimal required input parameters for an operation
90+ */
6591 export type MinimalInput < Op extends Operation > = InputParameters < Op [ 'parameters' ] > ;
6692
67- // Transforms API parameters based on their type:
68- // - query parameters are made optional (Partial)
69- // - header parameters have Accept and Content-Type removed since they're handled by the client
70- // - all other parameters (path, body) are kept as-is
71- // TODO: MI-199 should we be making params partial?
72- type TransformParam <
93+ /**
94+ * @description Makes properties optional if they're on the 'query' object
95+ */
96+ type MakeQueryParamsOptional <
7397 OpParams extends Operation [ 'parameters' ] ,
7498 K extends keyof OpParams ,
7599 > = K extends 'query' ? Partial < OpParams [ K ] > : OpParams [ K ] ;
76100
77- // Transforms operation parameters to make certain fields optional
101+ /**
102+ * @description Makes properties optional if they can be empty objects
103+ */
104+ type MakeEmptyObjectOptional < T > = {
105+ readonly [ K in keyof T as { } extends T [ K ] ? K : never ] ?: T [ K ] ;
106+ } & {
107+ readonly [ K in keyof T as { } extends T [ K ] ? never : K ] : T [ K ] ;
108+ } ;
109+
110+ /**
111+ * @description Prepares request parameters by making query params and any possibly empty params optional
112+ */
78113 type InputParameters < OpParams extends Operation [ 'parameters' ] > = MakeEmptyObjectOptional < {
79- [ K in keyof OpParams ] : TransformParam < OpParams , K > ;
114+ [ K in keyof OpParams ] : MakeQueryParamsOptional < OpParams , K > ;
80115 } > ;
81116}
82117
83- // Maps request lines to their corresponding operations
118+ /**
119+ * @description Maps request lines to their corresponding operations
120+ */
84121export type OperationIndex = Record < string , Operation > ;
85122
86123// Namespace for operation index utilities
87124export namespace OperationIndex {
88- // Filters operations to only include those with optional parameters
125+ /**
126+ * @description Filters operations to only include those with optional parameters
127+ */
89128 export type FilterOptionalParams < Ops extends OperationIndex > = {
90129 [ K in keyof Ops as { } extends Ops [ K ] [ 'parameters' ] ? K : never ] : Ops [ K ] ;
91130 } ;
92131}
93132
94- // Utility type that makes properties optional if they can be empty objects
95- type MakeEmptyObjectOptional < T > = {
96- readonly [ K in keyof T as { } extends T [ K ] ? K : never ] ?: T [ K ] ;
97- } & {
98- readonly [ K in keyof T as { } extends T [ K ] ? never : K ] : T [ K ] ;
99- } ;
100-
133+ /**
134+ * @description Resolves the path for a request
135+ * @example
136+ * ```ts
137+ * resolvePath('/products/{id}', { id: 123 })
138+ * // returns '/products/123'
139+ * ```
140+ */
101141export function resolvePath ( parameterizedPath : string , pathParams : Record < string , any > ) : string {
102142 return parameterizedPath
103143 . split ( '/' )
@@ -116,10 +156,14 @@ export function resolvePath(parameterizedPath: string, pathParams: Record<string
116156 . join ( '/' ) ;
117157}
118158
119- // Transport function type that handles making the actual API requests
159+ /**
160+ * @description Transport function type that handles making the actual API requests
161+ */
120162export type Transport = ( requestLine : string , params ?: Parameters ) => Promise < Response > ;
121163
122- // Configuration options for the fetch-based transport
164+ /**
165+ * @description Configuration options for the fetch-based transport
166+ */
123167export type FetchTransportOptions = {
124168 readonly baseUrl : string ;
125169 readonly headers : Record < string , string > ;
@@ -165,6 +209,20 @@ const defaultRetryConfig: Exclude<FetchTransportOptions['retry'], boolean | unde
165209 } ,
166210} ;
167211
212+ /**
213+ * @description Creates a fetch transport function
214+ * @example
215+ * ```ts
216+ * const transport = fetchTransport({
217+ * baseUrl: 'https://api.bigcommerce.com/stores/1234567890/v3',
218+ * headers: {
219+ * 'X-Auth-Token': '1234567890',
220+ * },
221+ * });
222+ * ```
223+ * @param options - The options for the fetch transport
224+ * @returns
225+ */
168226export function fetchTransport ( options : FetchTransportOptions ) : Transport {
169227 const { agent, baseUrl, headers, retry } = options ;
170228
0 commit comments