1
- import { Merge } from 'type-fest' ;
1
+ import { Merge , PartialDeep } from 'type-fest' ;
2
+ import asPromise from './as-promise' ;
3
+ import asStream , { ProxyStream } from './as-stream' ;
2
4
import * as errors from './errors' ;
5
+ import { normalizeArguments , mergeOptions } from './normalize-arguments' ;
6
+ import deepFreeze from './utils/deep-freeze' ;
3
7
import {
4
- Options ,
5
- Defaults ,
6
- NormalizedOptions ,
7
- Response ,
8
8
CancelableRequest ,
9
- URLOrOptions ,
9
+ ExtendOptions ,
10
10
HandlerFunction ,
11
- ExtendedOptions
11
+ NormalizedDefaults ,
12
+ NormalizedOptions ,
13
+ Options ,
14
+ Response ,
15
+ URLOrOptions
12
16
} from './utils/types' ;
13
- import deepFreeze from './utils/deep-freeze' ;
14
- import asPromise from './as-promise' ;
15
- import asStream , { ProxyStream } from './as-stream' ;
16
- import { normalizeArguments , mergeOptions } from './normalize-arguments' ;
17
- import { Hooks } from './known-hook-events' ;
18
17
19
18
export type HTTPAlias =
20
19
| 'get'
@@ -24,36 +23,39 @@ export type HTTPAlias =
24
23
| 'head'
25
24
| 'delete' ;
26
25
27
- export type ReturnStream = ( url : string | Options & { isStream : true } , options ?: Options & { isStream : true } ) => ProxyStream ;
28
- export type GotReturn = ProxyStream | CancelableRequest < Response > ;
26
+ export type ReturnStream = < T > ( url : string | Merge < Options , { isStream ? : true } > , options ?: Merge < Options , { isStream ? : true } > ) => ProxyStream < T > ;
27
+ export type GotReturn < T = unknown > = CancelableRequest < T > | ProxyStream < T > ;
29
28
30
29
const getPromiseOrStream = ( options : NormalizedOptions ) : GotReturn => options . isStream ? asStream ( options ) : asPromise ( options ) ;
31
30
32
- type OptionsOfDefaultResponseBody = Options & { isStream ?: false ; resolveBodyOnly ?: false ; responseType ?: 'default' } ;
33
- type OptionsOfTextResponseBody = Options & { isStream ?: false ; resolveBodyOnly ?: false ; responseType : 'text' } ;
34
- type OptionsOfJSONResponseBody = Options & { isStream ?: false ; resolveBodyOnly ?: false ; responseType : 'json' } ;
35
- type OptionsOfBufferResponseBody = Options & { isStream ?: false ; resolveBodyOnly ?: false ; responseType : 'buffer' } ;
31
+ const isGotInstance = ( value : any ) : value is Got => (
32
+ Reflect . has ( value , 'defaults' ) && Reflect . has ( value . defaults , 'options' )
33
+ ) ;
34
+
35
+ export type OptionsOfDefaultResponseBody = Merge < Options , { isStream ?: false ; resolveBodyOnly ?: false ; responseType ?: 'default' } > ;
36
+ type OptionsOfTextResponseBody = Merge < Options , { isStream ?: false ; resolveBodyOnly ?: false ; responseType : 'text' } > ;
37
+ type OptionsOfJSONResponseBody = Merge < Options , { isStream ?: false ; resolveBodyOnly ?: false ; responseType : 'json' } > ;
38
+ type OptionsOfBufferResponseBody = Merge < Options , { isStream ?: false ; resolveBodyOnly ?: false ; responseType : 'buffer' } > ;
36
39
type ResponseBodyOnly = { resolveBodyOnly : true } ;
37
40
38
41
interface GotFunctions {
39
42
// `asPromise` usage
40
- ( url : string | OptionsOfDefaultResponseBody , options ?: OptionsOfDefaultResponseBody ) : CancelableRequest < Response > ;
43
+ < T = string > ( url : string | OptionsOfDefaultResponseBody , options ?: OptionsOfDefaultResponseBody ) : CancelableRequest < Response < T > > ;
41
44
( url : string | OptionsOfTextResponseBody , options ?: OptionsOfTextResponseBody ) : CancelableRequest < Response < string > > ;
42
- ( url : string | OptionsOfJSONResponseBody , options ?: OptionsOfJSONResponseBody ) : CancelableRequest < Response < object > > ;
45
+ < T > ( url : string | OptionsOfJSONResponseBody , options ?: OptionsOfJSONResponseBody ) : CancelableRequest < Response < T > > ;
43
46
( url : string | OptionsOfBufferResponseBody , options ?: OptionsOfBufferResponseBody ) : CancelableRequest < Response < Buffer > > ;
44
-
45
- ( url : string | OptionsOfDefaultResponseBody & ResponseBodyOnly , options ?: OptionsOfDefaultResponseBody & ResponseBodyOnly ) : CancelableRequest < any > ;
46
- ( url : string | OptionsOfTextResponseBody & ResponseBodyOnly , options ?: OptionsOfTextResponseBody & ResponseBodyOnly ) : CancelableRequest < string > ;
47
- ( url : string | OptionsOfJSONResponseBody & ResponseBodyOnly , options ?: OptionsOfJSONResponseBody & ResponseBodyOnly ) : CancelableRequest < object > ;
48
- ( url : string | OptionsOfBufferResponseBody & ResponseBodyOnly , options ?: OptionsOfBufferResponseBody & ResponseBodyOnly ) : CancelableRequest < Buffer > ;
49
-
47
+ // `resolveBodyOnly` usage
48
+ < T = string > ( url : string | Merge < OptionsOfDefaultResponseBody , ResponseBodyOnly > , options ?: Merge < OptionsOfDefaultResponseBody , ResponseBodyOnly > ) : CancelableRequest < T > ;
49
+ ( url : string | Merge < OptionsOfTextResponseBody , ResponseBodyOnly > , options ?: Merge < OptionsOfTextResponseBody , ResponseBodyOnly > ) : CancelableRequest < string > ;
50
+ < T > ( url : string | Merge < OptionsOfJSONResponseBody , ResponseBodyOnly > , options ?: Merge < OptionsOfJSONResponseBody , ResponseBodyOnly > ) : CancelableRequest < T > ;
51
+ ( url : string | Merge < OptionsOfBufferResponseBody , ResponseBodyOnly > , options ?: Merge < OptionsOfBufferResponseBody , ResponseBodyOnly > ) : CancelableRequest < Buffer > ;
50
52
// `asStream` usage
51
- ( url : string | Options & { isStream : true } , options ?: Options & { isStream : true } ) : ProxyStream ;
53
+ < T > ( url : string | Merge < Options , { isStream : true } > , options ?: Merge < Options , { isStream : true } > ) : ProxyStream < T > ;
52
54
}
53
55
54
- export interface Got extends Merge < Record < HTTPAlias , GotFunctions > , GotFunctions > {
56
+ export interface Got extends Record < HTTPAlias , GotFunctions > , GotFunctions {
55
57
stream : GotStream ;
56
- defaults : Defaults | Readonly < Defaults > ;
58
+ defaults : NormalizedDefaults | Readonly < NormalizedDefaults > ;
57
59
GotError : typeof errors . GotError ;
58
60
CacheError : typeof errors . CacheError ;
59
61
RequestError : typeof errors . RequestError ;
@@ -65,9 +67,9 @@ export interface Got extends Merge<Record<HTTPAlias, GotFunctions>, GotFunctions
65
67
TimeoutError : typeof errors . TimeoutError ;
66
68
CancelError : typeof errors . CancelError ;
67
69
68
- extend ( ...instancesOrOptions : Array < Got | ExtendedOptions > ) : Got ;
70
+ extend ( ...instancesOrOptions : Array < Got | ExtendOptions > ) : Got ;
69
71
mergeInstances ( parent : Got , ...instances : Got [ ] ) : Got ;
70
- mergeOptions < T extends Options > ( ...sources : T [ ] ) : T & { hooks : Partial < Hooks > } ;
72
+ mergeOptions < T extends PartialDeep < Options > > ( ...sources : T [ ] ) : T ;
71
73
}
72
74
73
75
export interface GotStream extends Record < HTTPAlias , ReturnStream > {
@@ -85,11 +87,12 @@ const aliases: readonly HTTPAlias[] = [
85
87
86
88
export const defaultHandler : HandlerFunction = ( options , next ) => next ( options ) ;
87
89
88
- const create = ( defaults : Defaults ) : Got => {
90
+ const create = ( defaults : NormalizedDefaults & { _rawHandlers ?: HandlerFunction [ ] } ) : Got => {
89
91
// Proxy properties from next handlers
90
92
defaults . _rawHandlers = defaults . handlers ;
91
93
defaults . handlers = defaults . handlers . map ( fn => ( ( options , next ) => {
92
- let root : GotReturn ;
94
+ // This will be assigned by assigning result
95
+ let root ! : GotReturn ;
93
96
94
97
const result = fn ( options , newOptions => {
95
98
root = next ( newOptions ) ;
@@ -107,7 +110,7 @@ const create = (defaults: Defaults): Got => {
107
110
// @ts -ignore Because the for loop handles it for us, as well as the other Object.defines
108
111
const got : Got = ( url : URLOrOptions , options ?: Options ) : GotReturn => {
109
112
let iteration = 0 ;
110
- const iterateHandlers : HandlerFunction = newOptions => {
113
+ const iterateHandlers = ( newOptions : Parameters < HandlerFunction > [ 0 ] ) : ReturnType < HandlerFunction > => {
111
114
return defaults . handlers [ iteration ++ ] (
112
115
newOptions ,
113
116
// @ts -ignore TS doesn't know that it calls `getPromiseOrStream` at the end
@@ -116,7 +119,6 @@ const create = (defaults: Defaults): Got => {
116
119
} ;
117
120
118
121
try {
119
- // @ts -ignore This handler takes only one parameter.
120
122
return iterateHandlers ( normalizeArguments ( url , options , defaults ) ) ;
121
123
} catch ( error ) {
122
124
if ( options ?. isStream ) {
@@ -130,24 +132,22 @@ const create = (defaults: Defaults): Got => {
130
132
131
133
got . extend = ( ...instancesOrOptions ) => {
132
134
const optionsArray : Options [ ] = [ defaults . options ] ;
133
- let handlers : HandlerFunction [ ] = [ ...defaults . _rawHandlers ] ;
134
- let mutableDefaults : boolean ;
135
+ let handlers : HandlerFunction [ ] = [ ...defaults . _rawHandlers ! ] ;
136
+ let mutableDefaults : boolean | undefined ;
135
137
136
138
for ( const value of instancesOrOptions ) {
137
- if ( Reflect . has ( value , 'defaults' ) ) {
138
- optionsArray . push ( ( value as Got ) . defaults . options ) ;
139
-
140
- handlers . push ( ...( value as Got ) . defaults . _rawHandlers ) ;
141
-
142
- mutableDefaults = ( value as Got ) . defaults . mutableDefaults ;
139
+ if ( isGotInstance ( value ) ) {
140
+ optionsArray . push ( value . defaults . options ) ;
141
+ handlers . push ( ...value . defaults . _rawHandlers ! ) ;
142
+ mutableDefaults = value . defaults . mutableDefaults ;
143
143
} else {
144
- optionsArray . push ( value as ExtendedOptions ) ;
144
+ optionsArray . push ( value ) ;
145
145
146
146
if ( Reflect . has ( value , 'handlers' ) ) {
147
- handlers . push ( ...( value as ExtendedOptions ) . handlers ) ;
147
+ handlers . push ( ...value . handlers ) ;
148
148
}
149
149
150
- mutableDefaults = ( value as ExtendedOptions ) . mutableDefaults ;
150
+ mutableDefaults = value . mutableDefaults ;
151
151
}
152
152
}
153
153
@@ -160,7 +160,7 @@ const create = (defaults: Defaults): Got => {
160
160
return create ( {
161
161
options : mergeOptions ( ...optionsArray ) ,
162
162
handlers,
163
- mutableDefaults
163
+ mutableDefaults : Boolean ( mutableDefaults )
164
164
} ) ;
165
165
} ;
166
166
0 commit comments