diff --git a/index.js b/index.js index 9ec1b2fc..4bf2bc19 100644 --- a/index.js +++ b/index.js @@ -232,7 +232,10 @@ class Ky { this.request = new globalThis.Request(this._input, this._options); if (this._options.searchParams) { - const searchParams = '?' + new URLSearchParams(this._options.searchParams).toString(); + const textSearchParams = typeof this._options.searchParams === 'string' ? + this._options.searchParams.replace(/^\?/, '') : + new URLSearchParams(this._options.searchParams).toString(); + const searchParams = '?' + textSearchParams; const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams); // To provide correct form boundary, Content-Type header should be deleted each time when new Request instantiated from another one diff --git a/test/fetch.js b/test/fetch.js index 98b7844f..3829d6b2 100644 --- a/test/fetch.js +++ b/test/fetch.js @@ -10,9 +10,9 @@ test.serial('relative URLs are passed to fetch unresolved', async t => { t.is(await ky('/unicorn').text(), '/unicorn'); t.is(await ky('/unicorn', {searchParams: {foo: 'bar'}}).text(), '/unicorn?foo=bar'); - t.is(await ky('/unicorn#hash', {searchParams: 'foo'}).text(), '/unicorn?foo=#hash'); - t.is(await ky('/unicorn?old', {searchParams: 'new'}).text(), '/unicorn?new='); - t.is(await ky('/unicorn?old#hash', {searchParams: 'new'}).text(), '/unicorn?new=#hash'); + t.is(await ky('/unicorn#hash', {searchParams: 'foo'}).text(), '/unicorn?foo#hash'); + t.is(await ky('/unicorn?old', {searchParams: 'new'}).text(), '/unicorn?new'); + t.is(await ky('/unicorn?old#hash', {searchParams: 'new'}).text(), '/unicorn?new#hash'); t.is(await ky('unicorn', {prefixUrl: '/api/'}).text(), '/api/unicorn'); globalThis.fetch = originalFetch; }); @@ -27,8 +27,8 @@ test('fetch option takes a custom fetch function', async t => { t.is(await ky('/unicorn', {fetch: customFetch}).text(), '/unicorn'); t.is(await ky('/unicorn', {fetch: customFetch, searchParams: {foo: 'bar'}}).text(), '/unicorn?foo=bar'); - t.is(await ky('/unicorn#hash', {fetch: customFetch, searchParams: 'foo'}).text(), '/unicorn?foo=#hash'); - t.is(await ky('/unicorn?old', {fetch: customFetch, searchParams: 'new'}).text(), '/unicorn?new='); - t.is(await ky('/unicorn?old#hash', {fetch: customFetch, searchParams: 'new'}).text(), '/unicorn?new=#hash'); + t.is(await ky('/unicorn#hash', {fetch: customFetch, searchParams: 'foo'}).text(), '/unicorn?foo#hash'); + t.is(await ky('/unicorn?old', {fetch: customFetch, searchParams: 'new'}).text(), '/unicorn?new'); + t.is(await ky('/unicorn?old#hash', {fetch: customFetch, searchParams: 'new'}).text(), '/unicorn?new#hash'); t.is(await ky('unicorn', {fetch: customFetch, prefixUrl: '/api/'}).text(), '/api/unicorn'); }); diff --git a/test/main.js b/test/main.js index b7e8aded..b3733125 100644 --- a/test/main.js +++ b/test/main.js @@ -341,11 +341,13 @@ test('searchParams option', async t => { }; const searchParameters = new URLSearchParams(arrayParameters); const stringParameters = '?cats=meow&dogs=true&opossums=false'; + const customStringParameters = '?cats&dogs[0]=true&dogs[1]=false'; t.is(await ky(server.url, {searchParams: arrayParameters}).text(), stringParameters); t.is(await ky(server.url, {searchParams: objectParameters}).text(), stringParameters); t.is(await ky(server.url, {searchParams: searchParameters}).text(), stringParameters); t.is(await ky(server.url, {searchParams: stringParameters}).text(), stringParameters); + t.is(await ky(server.url, {searchParams: customStringParameters}).text(), customStringParameters); await server.close(); });