diff --git a/package.json b/package.json index 76afcd2b1e..5fdcc596c6 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "@types/chai": "^4.3.4", "@types/chai-as-promised": "^7.1.5", "@types/mocha": "^10.0.1", - "@types/qs": "^6.9.7", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", "chai": "^4.3.6", @@ -55,8 +54,7 @@ "nanoid": "^3.2.0" }, "dependencies": { - "@types/node": ">=8.1.0", - "qs": "^6.11.0" + "@types/node": ">=8.1.0" }, "license": "MIT", "scripts": { diff --git a/src/utils.ts b/src/utils.ts index 005256d56e..67dd5c58fb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,3 @@ -import * as qs from 'qs'; import { RequestData, UrlInterpolator, @@ -43,18 +42,45 @@ export function isOptionsHash(o: unknown): boolean | unknown { * Stringifies an Object, accommodating nested objects * (forming the conventional key 'parent[child]=value') */ -export function stringifyRequestData(data: RequestData | string): string { - return ( - qs - .stringify(data, { - serializeDate: (d: Date) => Math.floor(d.getTime() / 1000).toString(), - }) - // Don't use strict form encoding by changing the square bracket control - // characters back to their literals. This is fine by the server, and - // makes these parameter strings easier to read. - .replace(/%5B/g, '[') - .replace(/%5D/g, ']') - ); +export function stringifyRequestData( + data: Record | string +): string { + if (typeof data === 'string') { + return data; + } + + const params = new URLSearchParams(); + + const serializeDate = (d: Date): string => + Math.floor(d.getTime() / 1000).toString(); + + function addToParams(key: string, value: any): void { + if (value instanceof Date) { + params.append(key, serializeDate(value)); + } else if (Array.isArray(value)) { + value.forEach((v, i) => { + addToParams(`${key}[${i}]`, v); + }); + } else if (typeof value === 'object' && value !== null) { + Object.entries(value).forEach(([k, v]) => { + addToParams(`${key}[${k}]`, v); + }); + } else if (value === null) { + params.append(key, ''); + } else { + params.append(key, value); + } + } + + Object.entries(data).forEach(([key, value]) => { + addToParams(key, value); + }); + + return params + .toString() + .replace(/\+/g, '%20') + .replace(/%5B/g, '[') + .replace(/%5D/g, ']'); } /** diff --git a/test/resources/OAuth.spec.js b/test/resources/OAuth.spec.js index fba0499f97..cdec43ca13 100644 --- a/test/resources/OAuth.spec.js +++ b/test/resources/OAuth.spec.js @@ -4,7 +4,7 @@ const stripe = require('../testUtils.js').getSpyableStripe(); const expect = require('chai').expect; const URL = require('url'); -const qs = require('qs'); +const qs = require('querystring'); describe('OAuth', () => { describe('authorize', () => { diff --git a/yarn.lock b/yarn.lock index ed4ae6c1fc..9244e47c78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -459,11 +459,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.3.tgz#78a6d7ec962b596fc2d2ec102c4dd3ef073fea6a" integrity sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A== -"@types/qs@^6.9.7": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - "@typescript-eslint/eslint-plugin@^4.33.0": version "4.33.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" @@ -2638,13 +2633,6 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@^6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"