diff --git a/package-lock.json b/package-lock.json index 762469f5..aa5a046d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "debug": "^4.3.4", "decompress-response": "^7.0.0", "follow-redirects": "^1.15.2", - "form-urlencoded": "^6.1.0", "into-stream": "^6.0.0", "is-plain-object": "^5.0.0", "is-retry-allowed": "^2.2.0", @@ -6975,11 +6974,6 @@ "node": ">=8.0.0" } }, - "node_modules/form-urlencoded": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/form-urlencoded/-/form-urlencoded-6.1.0.tgz", - "integrity": "sha512-lc1Qd9nnEewXKoiPjIA1n38M5STbyY6krgoegsg7SsAt2b98HZKe25KaJvKFBwQaOcmh8FP7JbXVC7gocZw+XQ==" - }, "node_modules/from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", diff --git a/package.json b/package.json index f0abe649..7b195153 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,6 @@ "debug": "^4.3.4", "decompress-response": "^7.0.0", "follow-redirects": "^1.15.2", - "form-urlencoded": "^6.1.0", "into-stream": "^6.0.0", "is-plain-object": "^5.0.0", "is-retry-allowed": "^2.2.0", diff --git a/src/middleware/urlEncoded.ts b/src/middleware/urlEncoded.ts index cac26854..0547aa15 100644 --- a/src/middleware/urlEncoded.ts +++ b/src/middleware/urlEncoded.ts @@ -1,10 +1,35 @@ -import encode from 'form-urlencoded' import {isPlainObject} from 'is-plain-object' -const isBuffer = (obj: any) => - !!obj.constructor && - typeof obj.constructor.isBuffer === 'function' && - obj.constructor.isBuffer(obj) +import {isBuffer} from '../util/isBuffer' + +function encode(data: Record>): string { + const query = new URLSearchParams() + + const nest = (name: string, _value: unknown) => { + const value = _value instanceof Set ? Array.from(_value) : _value + if (Array.isArray(value)) { + if (value.length) { + for (const index in value) { + nest(`${name}[${index}]`, value[index]) + } + } else { + query.append(`${name}[]`, '') + } + } else if (typeof value === 'object' && value !== null) { + for (const [key, obj] of Object.entries(value)) { + nest(`${name}[${key}]`, obj) + } + } else { + query.append(name, value as string) + } + } + + for (const [key, value] of Object.entries(data)) { + nest(key, value) + } + + return query.toString() +} /** @public */ export function urlEncoded(): any { @@ -22,12 +47,14 @@ export function urlEncoded(): any { return options } - return Object.assign({}, options, { + return { + ...options, body: encode(options.body), - headers: Object.assign({}, options.headers, { + headers: { + ...options.headers, 'Content-Type': 'application/x-www-form-urlencoded', - }), - }) + }, + } }, } } diff --git a/test-deno/import_map.json b/test-deno/import_map.json index ad6d6c46..a4b01301 100644 --- a/test-deno/import_map.json +++ b/test-deno/import_map.json @@ -2,7 +2,6 @@ "imports": { "create-error-class": "https://esm.sh/create-error-class@^3.0.2", "debug": "https://esm.sh/debug@^4.3.4", - "form-urlencoded": "https://esm.sh/form-urlencoded@^6.1.0", "is-plain-object": "https://esm.sh/is-plain-object@^5.0.0", "parse-headers": "https://esm.sh/parse-headers@^2.0.5" } diff --git a/test/urlEncoded.test.ts b/test/urlEncoded.test.ts index 5c35a79b..1a60b92e 100644 --- a/test/urlEncoded.test.ts +++ b/test/urlEncoded.test.ts @@ -55,7 +55,8 @@ describe('urlEncoded middleware', () => { 'obj[prop2][0]': 'elem', str: 'val', emoji: '😀', - set: '1,two', + 'set[0]': '1', + 'set[1]': 'two', }) })