@@ -204,7 +204,7 @@ const appendSearchParameters = (target: any, source: any): URLSearchParams => {
204204} ;
205205
206206// TODO: Make this strongly-typed (no `any`).
207- export const deepMerge = < T > ( ...sources : Array < Partial < T > | undefined > ) : T => {
207+ const deepMergeInternal = < T > ( isRoot : boolean , ...sources : Array < Partial < T > | undefined > ) : T => {
208208 let returnValue : any = { } ;
209209 let headers : KyHeadersInit = { } ;
210210 let hooks = { } ;
@@ -264,8 +264,17 @@ export const deepMerge = <T>(...sources: Array<Partial<T> | undefined>): T => {
264264 continue ;
265265 }
266266
267+ // `retry` accepts a number as shorthand for `{limit: number}`. Expand it before
268+ // merging so extending a numeric `retry` with an object keeps the limit instead
269+ // of dropping it (e.g. `ky.create({retry: 3}).extend({retry: {methods: ['get']}})`).
270+ // Scoped to the root options level so it never rewrites nested user data that
271+ // happens to contain a `retry` key (e.g. a `json` request body).
272+ if ( isRoot && key === 'retry' && isObject ( value ) && ! isReplace && typeof returnValue [ key ] === 'number' ) {
273+ returnValue = { ...returnValue , [ key ] : { limit : returnValue [ key ] } } ;
274+ }
275+
267276 if ( isObject ( value ) && ! isReplace && key in returnValue ) {
268- value = deepMerge ( returnValue [ key ] , value ) ;
277+ value = deepMergeInternal ( false , returnValue [ key ] , value ) ;
269278 }
270279
271280 returnValue = { ...returnValue , [ key ] : value } ;
@@ -310,3 +319,6 @@ export const deepMerge = <T>(...sources: Array<Partial<T> | undefined>): T => {
310319
311320 return returnValue ;
312321} ;
322+
323+ export const deepMerge = < T > ( ...sources : Array < Partial < T > | undefined > ) : T =>
324+ deepMergeInternal < T > ( true , ...sources ) ;
0 commit comments