From d4f07913c8c711c03958e2ff03f5d23d2f51c862 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Fri, 23 Sep 2022 15:15:03 -0700 Subject: [PATCH 01/12] Migrate other Stripe infrastructure to TS --- .eslintrc.js | 1 + lib/Webhooks.js | 6 +++-- lib/crypto/SubtleCryptoProvider.js | 2 +- lib/multipart.js | 9 ++++--- lib/net/FetchHttpClient.js | 3 ++- lib/net/NodeHttpClient.js | 3 ++- lib/utils.js | 9 ++++--- src/Error.ts | 4 +-- ...ourceNamespace.js => ResourceNamespace.ts} | 0 src/{Webhooks.js => Webhooks.ts} | 10 +++++--- .../{CryptoProvider.js => CryptoProvider.ts} | 6 ++--- ...ryptoProvider.js => NodeCryptoProvider.ts} | 13 ++++++---- ...ptoProvider.js => SubtleCryptoProvider.ts} | 10 +++++--- src/{multipart.js => multipart.ts} | 11 +++++--- ...{FetchHttpClient.js => FetchHttpClient.ts} | 10 ++++++-- src/net/{HttpClient.js => HttpClient.ts} | 14 +++++++++-- .../{NodeHttpClient.js => NodeHttpClient.ts} | 9 +++++-- src/{utils.js => utils.ts} | 25 +++++++++++++++---- 18 files changed, 100 insertions(+), 45 deletions(-) rename src/{ResourceNamespace.js => ResourceNamespace.ts} (100%) rename src/{Webhooks.js => Webhooks.ts} (96%) rename src/crypto/{CryptoProvider.js => CryptoProvider.ts} (88%) rename src/crypto/{NodeCryptoProvider.js => NodeCryptoProvider.ts} (58%) rename src/crypto/{SubtleCryptoProvider.js => SubtleCryptoProvider.ts} (89%) rename src/{multipart.js => multipart.ts} (91%) rename src/net/{FetchHttpClient.js => FetchHttpClient.ts} (95%) rename src/net/{HttpClient.js => HttpClient.ts} (82%) rename src/net/{NodeHttpClient.js => NodeHttpClient.ts} (93%) rename src/{utils.js => utils.ts} (97%) diff --git a/.eslintrc.js b/.eslintrc.js index 7eecf96137..041cd2c19e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -271,6 +271,7 @@ module.exports = { '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/explicit-function-return-type': 0, '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-this-alias': 0, 'prefer-rest-params': 'off', }, }, diff --git a/lib/Webhooks.js b/lib/Webhooks.js index cfd9232527..9fb4850523 100644 --- a/lib/Webhooks.js +++ b/lib/Webhooks.js @@ -1,8 +1,10 @@ 'use strict'; const utils = require('./utils'); -const {StripeError, StripeSignatureVerificationError} = require('./Error'); +const _Error = require('./Error'); +const {StripeError, StripeSignatureVerificationError} = _Error; const Webhook = { DEFAULT_TOLERANCE: 300, + signature: null, constructEvent(payload, header, secret, tolerance, cryptoProvider) { this.signature.verifyHeader( payload, @@ -205,7 +207,7 @@ function parseHeader(header, scheme) { (accum, item) => { const kv = item.split('='); if (kv[0] === 't') { - accum.timestamp = kv[1]; + accum.timestamp = parseInt(kv[1], 10); } if (kv[0] === scheme) { accum.signatures.push(kv[1]); diff --git a/lib/crypto/SubtleCryptoProvider.js b/lib/crypto/SubtleCryptoProvider.js index 6ff0e2b3c2..cbf5d01373 100644 --- a/lib/crypto/SubtleCryptoProvider.js +++ b/lib/crypto/SubtleCryptoProvider.js @@ -21,7 +21,7 @@ class SubtleCryptoProvider extends CryptoProvider { } /** @override */ async computeHMACSignatureAsync(payload, secret) { - const encoder = new TextEncoder('utf-8'); + const encoder = new TextEncoder(); const key = await this.subtleCrypto.importKey( 'raw', encoder.encode(secret), diff --git a/lib/multipart.js b/lib/multipart.js index bb186e00db..d88d468b1f 100644 --- a/lib/multipart.js +++ b/lib/multipart.js @@ -1,6 +1,7 @@ 'use strict'; const utils = require('./utils'); -const {StripeError} = require('./Error'); +const _Error = require('./Error'); +const {StripeError} = _Error; class StreamProcessingError extends StripeError {} // Method for formatting HTTP body for the multipart/form-data specification // Mostly taken from Fermata.js @@ -26,7 +27,7 @@ const multipartDataGenerator = (method, data, headers) => { for (const k in flattenedData) { const v = flattenedData[k]; push(`--${segno}`); - if (v.hasOwnProperty('data')) { + if (Object.prototype.hasOwnProperty.call(v, 'data')) { push( `Content-Disposition: form-data; name=${q(k)}; filename=${q( v.name || 'blob' @@ -79,4 +80,6 @@ const multipartRequestDataProcessor = (method, data, headers, callback) => { const buffer = multipartDataGenerator(method, data, headers); return callback(null, buffer); }; -module.exports.multipartRequestDataProcessor = multipartRequestDataProcessor; +module.exports = { + multipartRequestDataProcessor: multipartRequestDataProcessor, +}; diff --git a/lib/net/FetchHttpClient.js b/lib/net/FetchHttpClient.js index e57891b8cd..195b1bb0c6 100644 --- a/lib/net/FetchHttpClient.js +++ b/lib/net/FetchHttpClient.js @@ -1,5 +1,6 @@ 'use strict'; -const {HttpClient, HttpClientResponse} = require('./HttpClient'); +const _HttpClient = require('./HttpClient'); +const {HttpClient, HttpClientResponse} = _HttpClient; /** * HTTP client which uses a `fetch` function to issue requests. * diff --git a/lib/net/NodeHttpClient.js b/lib/net/NodeHttpClient.js index 1f9d12c4d8..c5712dfe2f 100644 --- a/lib/net/NodeHttpClient.js +++ b/lib/net/NodeHttpClient.js @@ -1,7 +1,8 @@ 'use strict'; const http = require('http'); const https = require('https'); -const {HttpClient, HttpClientResponse} = require('./HttpClient'); +const _HttpClient = require('./HttpClient'); +const {HttpClient, HttpClientResponse} = _HttpClient; const defaultHttpAgent = new http.Agent({keepAlive: true}); const defaultHttpsAgent = new https.Agent({keepAlive: true}); /** diff --git a/lib/utils.js b/lib/utils.js index 9efd90fd63..d88ffb9d2e 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -31,7 +31,7 @@ const DEPRECATED_OPTIONS = { stripeVersion: 'apiVersion', }; const DEPRECATED_OPTIONS_KEYS = Object.keys(DEPRECATED_OPTIONS); -const utils = (module.exports = { +const utils = { isOptionsHash(o) { return ( o && @@ -342,7 +342,7 @@ const utils = (module.exports = { const value = obj[key]; const newKey = prevKey ? `${prevKey}[${key}]` : key; if (utils.isObject(value)) { - if (!Buffer.isBuffer(value) && !value.hasOwnProperty('data')) { + if (!Buffer.isBuffer(value) && !hasOwn(value, 'data')) { // Non-buffer non-file Objects are recursively flattened return step(value, newKey); } else { @@ -355,7 +355,7 @@ const utils = (module.exports = { } }); }; - step(data); + step(data, null); return result; }, /** @@ -386,7 +386,7 @@ const utils = (module.exports = { platform: process.platform, }; }, -}); +}; function emitWarning(warning) { if (typeof process.emitWarning !== 'function') { return console.warn( @@ -395,3 +395,4 @@ function emitWarning(warning) { } return process.emitWarning(warning, 'Stripe'); } +module.exports = utils; diff --git a/src/Error.ts b/src/Error.ts index c5de62ea0c..3a9cc390aa 100644 --- a/src/Error.ts +++ b/src/Error.ts @@ -18,7 +18,7 @@ type StripeRawError = { doc_url?: string; decline_code?: string; param?: string; - detail?: string; + detail?: any; charge?: string; payment_method_type?: string; @@ -44,7 +44,7 @@ class StripeError extends Error { readonly code?: string; readonly doc_url?: string; readonly param?: string; - readonly detail?: string; + readonly detail?: any; readonly statusCode?: number; readonly charge?: string; readonly decline_code?: string; diff --git a/src/ResourceNamespace.js b/src/ResourceNamespace.ts similarity index 100% rename from src/ResourceNamespace.js rename to src/ResourceNamespace.ts diff --git a/src/Webhooks.js b/src/Webhooks.ts similarity index 96% rename from src/Webhooks.js rename to src/Webhooks.ts index ffbe2004a9..0d3a7683e2 100644 --- a/src/Webhooks.js +++ b/src/Webhooks.ts @@ -1,10 +1,12 @@ 'use strict'; -const utils = require('./utils'); -const {StripeError, StripeSignatureVerificationError} = require('./Error'); +import utils = require('./utils'); +import _Error = require('./Error'); +const {StripeError, StripeSignatureVerificationError} = _Error; const Webhook = { DEFAULT_TOLERANCE: 300, // 5 minutes + signature: null, constructEvent(payload, header, secret, tolerance, cryptoProvider) { this.signature.verifyHeader( @@ -242,7 +244,7 @@ function parseHeader(header, scheme) { const kv = item.split('='); if (kv[0] === 't') { - accum.timestamp = kv[1]; + accum.timestamp = parseInt(kv[1], 10); } if (kv[0] === scheme) { @@ -274,4 +276,4 @@ function getNodeCryptoProvider() { Webhook.signature = signature; -module.exports = Webhook; +export = Webhook; diff --git a/src/crypto/CryptoProvider.js b/src/crypto/CryptoProvider.ts similarity index 88% rename from src/crypto/CryptoProvider.js rename to src/crypto/CryptoProvider.ts index 8f038d06ca..f7be333d61 100644 --- a/src/crypto/CryptoProvider.js +++ b/src/crypto/CryptoProvider.ts @@ -13,7 +13,7 @@ class CryptoProvider { * - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd' * - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43 */ - computeHMACSignature(payload, secret) { + computeHMACSignature(payload: string, secret: string): string { throw new Error('computeHMACSignature not implemented.'); } @@ -28,9 +28,9 @@ class CryptoProvider { * - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd' * - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43 */ - computeHMACSignatureAsync(payload, secret) { + computeHMACSignatureAsync(payload: string, secret: string): Promise { throw new Error('computeHMACSignatureAsync not implemented.'); } } -module.exports = CryptoProvider; +export = CryptoProvider; diff --git a/src/crypto/NodeCryptoProvider.js b/src/crypto/NodeCryptoProvider.ts similarity index 58% rename from src/crypto/NodeCryptoProvider.js rename to src/crypto/NodeCryptoProvider.ts index 83c2037ea2..9963825f47 100644 --- a/src/crypto/NodeCryptoProvider.js +++ b/src/crypto/NodeCryptoProvider.ts @@ -1,15 +1,15 @@ 'use strict'; -const crypto = require('crypto'); +import crypto = require('crypto'); -const CryptoProvider = require('./CryptoProvider'); +import CryptoProvider = require('./CryptoProvider'); /** * `CryptoProvider which uses the Node `crypto` package for its computations. */ class NodeCryptoProvider extends CryptoProvider { /** @override */ - computeHMACSignature(payload, secret) { + computeHMACSignature(payload: string, secret: string): string { return crypto .createHmac('sha256', secret) .update(payload, 'utf8') @@ -17,10 +17,13 @@ class NodeCryptoProvider extends CryptoProvider { } /** @override */ - async computeHMACSignatureAsync(payload, secret) { + async computeHMACSignatureAsync( + payload: string, + secret: string + ): Promise { const signature = await this.computeHMACSignature(payload, secret); return signature; } } -module.exports = NodeCryptoProvider; +export = NodeCryptoProvider; diff --git a/src/crypto/SubtleCryptoProvider.js b/src/crypto/SubtleCryptoProvider.ts similarity index 89% rename from src/crypto/SubtleCryptoProvider.js rename to src/crypto/SubtleCryptoProvider.ts index 45aa40dd46..762bbaaf9c 100644 --- a/src/crypto/SubtleCryptoProvider.js +++ b/src/crypto/SubtleCryptoProvider.ts @@ -1,6 +1,6 @@ 'use strict'; -const CryptoProvider = require('./CryptoProvider'); +import CryptoProvider = require('./CryptoProvider'); /** * `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API. @@ -8,6 +8,8 @@ const CryptoProvider = require('./CryptoProvider'); * This only supports asynchronous operations. */ class SubtleCryptoProvider extends CryptoProvider { + subtleCrypto: any; + constructor(subtleCrypto) { super(); @@ -18,7 +20,7 @@ class SubtleCryptoProvider extends CryptoProvider { } /** @override */ - computeHMACSignature(payload, secret) { + computeHMACSignature(payload: string, secret: string): string { throw new Error( 'SubtleCryptoProvider cannot be used in a synchronous context.' ); @@ -26,7 +28,7 @@ class SubtleCryptoProvider extends CryptoProvider { /** @override */ async computeHMACSignatureAsync(payload, secret) { - const encoder = new TextEncoder('utf-8'); + const encoder = new TextEncoder(); const key = await this.subtleCrypto.importKey( 'raw', @@ -66,4 +68,4 @@ for (let i = 0; i < byteHexMapping.length; i++) { byteHexMapping[i] = i.toString(16).padStart(2, '0'); } -module.exports = SubtleCryptoProvider; +export = SubtleCryptoProvider; diff --git a/src/multipart.js b/src/multipart.ts similarity index 91% rename from src/multipart.js rename to src/multipart.ts index 90682aedda..328452fdc8 100644 --- a/src/multipart.js +++ b/src/multipart.ts @@ -1,7 +1,8 @@ 'use strict'; -const utils = require('./utils'); -const {StripeError} = require('./Error'); +import utils = require('./utils'); +import _Error = require('./Error'); +const {StripeError} = _Error; class StreamProcessingError extends StripeError {} @@ -33,7 +34,7 @@ const multipartDataGenerator = (method, data, headers) => { for (const k in flattenedData) { const v = flattenedData[k]; push(`--${segno}`); - if (v.hasOwnProperty('data')) { + if (Object.prototype.hasOwnProperty.call(v, 'data')) { push( `Content-Disposition: form-data; name=${q(k)}; filename=${q( v.name || 'blob' @@ -93,4 +94,6 @@ const multipartRequestDataProcessor = (method, data, headers, callback) => { return callback(null, buffer); }; -module.exports.multipartRequestDataProcessor = multipartRequestDataProcessor; +export = { + multipartRequestDataProcessor: multipartRequestDataProcessor, +}; diff --git a/src/net/FetchHttpClient.js b/src/net/FetchHttpClient.ts similarity index 95% rename from src/net/FetchHttpClient.js rename to src/net/FetchHttpClient.ts index 431282cd19..3a21ba10f1 100644 --- a/src/net/FetchHttpClient.js +++ b/src/net/FetchHttpClient.ts @@ -1,6 +1,7 @@ 'use strict'; -const {HttpClient, HttpClientResponse} = require('./HttpClient'); +import _HttpClient = require('./HttpClient'); +const {HttpClient, HttpClientResponse} = _HttpClient; /** * HTTP client which uses a `fetch` function to issue requests. @@ -11,6 +12,9 @@ const {HttpClient, HttpClientResponse} = require('./HttpClient'); * node-fetch package (https://github.com/node-fetch/node-fetch). */ class FetchHttpClient extends HttpClient { + _fetchFn: any; + _res: any; + constructor(fetchFn) { super(); this._fetchFn = fetchFn; @@ -88,6 +92,8 @@ class FetchHttpClient extends HttpClient { } class FetchHttpClientResponse extends HttpClientResponse { + _res: any; + constructor(res) { super( res.status, @@ -135,4 +141,4 @@ class FetchHttpClientResponse extends HttpClientResponse { } } -module.exports = {FetchHttpClient, FetchHttpClientResponse}; +export = {FetchHttpClient, FetchHttpClientResponse}; diff --git a/src/net/HttpClient.js b/src/net/HttpClient.ts similarity index 82% rename from src/net/HttpClient.js rename to src/net/HttpClient.ts index b309ce7d9d..3c5baefbc3 100644 --- a/src/net/HttpClient.js +++ b/src/net/HttpClient.ts @@ -1,5 +1,7 @@ 'use strict'; +type TimeoutError = TypeError & {code?: string}; + /** * Encapsulates the logic for issuing a request to the Stripe API. * @@ -10,6 +12,9 @@ * returning their own response class when making requests. */ class HttpClient { + static CONNECTION_CLOSED_ERROR_CODES: string[]; + static TIMEOUT_ERROR_CODE: string; + /** The client name used for diagnostics. */ getClientName() { throw new Error('getClientName not implemented.'); @@ -30,7 +35,9 @@ class HttpClient { /** Helper to make a consistent timeout error across implementations. */ static makeTimeoutError() { - const timeoutErr = new TypeError(HttpClient.TIMEOUT_ERROR_CODE); + const timeoutErr: TimeoutError = new TypeError( + HttpClient.TIMEOUT_ERROR_CODE + ); timeoutErr.code = HttpClient.TIMEOUT_ERROR_CODE; return timeoutErr; } @@ -40,6 +47,9 @@ HttpClient.CONNECTION_CLOSED_ERROR_CODES = ['ECONNRESET', 'EPIPE']; HttpClient.TIMEOUT_ERROR_CODE = 'ETIMEDOUT'; class HttpClientResponse { + _statusCode: number; + _headers: object; + constructor(statusCode, headers) { this._statusCode = statusCode; this._headers = headers; @@ -66,4 +76,4 @@ class HttpClientResponse { } } -module.exports = {HttpClient, HttpClientResponse}; +export = {HttpClient, HttpClientResponse}; diff --git a/src/net/NodeHttpClient.js b/src/net/NodeHttpClient.ts similarity index 93% rename from src/net/NodeHttpClient.js rename to src/net/NodeHttpClient.ts index 222a446ce7..f34358f748 100644 --- a/src/net/NodeHttpClient.js +++ b/src/net/NodeHttpClient.ts @@ -3,7 +3,8 @@ const http = require('http'); const https = require('https'); -const {HttpClient, HttpClientResponse} = require('./HttpClient'); +import _HttpClient = require('./HttpClient'); +const {HttpClient, HttpClientResponse} = _HttpClient; const defaultHttpAgent = new http.Agent({keepAlive: true}); const defaultHttpsAgent = new https.Agent({keepAlive: true}); @@ -13,6 +14,8 @@ const defaultHttpsAgent = new https.Agent({keepAlive: true}); * requests.` */ class NodeHttpClient extends HttpClient { + _agent: any; + constructor(agent) { super(); this._agent = agent; @@ -86,6 +89,8 @@ class NodeHttpClient extends HttpClient { } class NodeHttpClientResponse extends HttpClientResponse { + _res: any; + constructor(res) { super(res.statusCode, res.headers || {}); this._res = res; @@ -122,4 +127,4 @@ class NodeHttpClientResponse extends HttpClientResponse { } } -module.exports = {NodeHttpClient, NodeHttpClientResponse}; +export = {NodeHttpClient, NodeHttpClientResponse}; diff --git a/src/utils.js b/src/utils.ts similarity index 97% rename from src/utils.js rename to src/utils.ts index 7eed41defd..1a75f72732 100644 --- a/src/utils.js +++ b/src/utils.ts @@ -37,7 +37,20 @@ const DEPRECATED_OPTIONS = { }; const DEPRECATED_OPTIONS_KEYS = Object.keys(DEPRECATED_OPTIONS); -const utils = (module.exports = { +type Settings = { + timeout?: number; + maxNetworkRetries?: number; +}; + +type Options = { + auth?: any; + host?: any; + settings?: Settings; + streaming?: boolean; + headers?: {[header: string]: string}; +}; + +const utils = { isOptionsHash(o) { return ( o && @@ -140,7 +153,7 @@ const utils = (module.exports = { * Return the options hash from a list of arguments */ getOptionsFromArgs: (args) => { - const opts = { + const opts: Options = { auth: null, headers: {}, settings: {}, @@ -388,7 +401,7 @@ const utils = (module.exports = { const newKey = prevKey ? `${prevKey}[${key}]` : key; if (utils.isObject(value)) { - if (!Buffer.isBuffer(value) && !value.hasOwnProperty('data')) { + if (!Buffer.isBuffer(value) && !hasOwn(value, 'data')) { // Non-buffer non-file Objects are recursively flattened return step(value, newKey); } else { @@ -402,7 +415,7 @@ const utils = (module.exports = { }); }; - step(data); + step(data, null); return result; }, @@ -438,7 +451,7 @@ const utils = (module.exports = { platform: process.platform, }; }, -}); +}; function emitWarning(warning) { if (typeof process.emitWarning !== 'function') { @@ -449,3 +462,5 @@ function emitWarning(warning) { return process.emitWarning(warning, 'Stripe'); } + +export = utils; From 133d4a2cbb81e43cf5915d5a1cfda4b544e0a7c5 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Mon, 26 Sep 2022 12:27:50 -0700 Subject: [PATCH 02/12] Reviewer comments --- .eslintrc.js | 1 - lib/Webhooks.js | 4 ++++ lib/utils.js | 1 + package.json | 2 +- src/Error.ts | 4 ++-- src/Webhooks.ts | 4 ++++ src/utils.ts | 1 + yarn.lock | 8 ++++---- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 041cd2c19e..7eecf96137 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -271,7 +271,6 @@ module.exports = { '@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/explicit-function-return-type': 0, '@typescript-eslint/no-var-requires': 0, - '@typescript-eslint/no-this-alias': 0, 'prefer-rest-params': 'off', }, }, diff --git a/lib/Webhooks.js b/lib/Webhooks.js index 9fb4850523..fd6a0504fd 100644 --- a/lib/Webhooks.js +++ b/lib/Webhooks.js @@ -144,6 +144,7 @@ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) { if (!details || details.timestamp === -1) { throw new StripeSignatureVerificationError({ message: 'Unable to extract timestamp and signatures from header', + // @ts-expect-error Type '{ decodedHeader: any; decodedPayload: any; }' is not assignable to type 'string'. detail: { decodedHeader, decodedPayload, @@ -153,6 +154,7 @@ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) { if (!details.signatures.length) { throw new StripeSignatureVerificationError({ message: 'No signatures found with expected scheme', + // @ts-expect-error Type '{ decodedHeader: any; decodedPayload: any; }' is not assignable to type 'string'. detail: { decodedHeader, decodedPayload, @@ -181,6 +183,7 @@ function validateComputedSignature( 'No signatures found matching the expected signature for payload.' + ' Are you passing the raw request body you received from Stripe?' + ' https://github.com/stripe/stripe-node#webhook-signing', + // @ts-expect-error Type '{ header: any; payload: any; }' is not assignable to type 'string'. detail: { header, payload, @@ -191,6 +194,7 @@ function validateComputedSignature( if (tolerance > 0 && timestampAge > tolerance) { throw new StripeSignatureVerificationError({ message: 'Timestamp outside the tolerance zone', + // @ts-expect-error detail: { header, payload, diff --git a/lib/utils.js b/lib/utils.js index d88ffb9d2e..c1b48eb913 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -189,6 +189,7 @@ const utils = { * Provide simple "Class" extension mechanism */ protoExtend(sub) { + // eslint-disable-next-line @typescript-eslint/no-this-alias const Super = this; const Constructor = hasOwn(sub, 'constructor') ? sub.constructor diff --git a/package.json b/package.json index ba4f71cf36..2a1c8f91d7 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node-fetch": "^2.6.2", "nyc": "^15.1.0", "prettier": "^1.16.4", - "typescript": "^3.7.2" + "typescript": "^3.9.0" }, "resolutions": { "ansi-regex": "5.0.1", diff --git a/src/Error.ts b/src/Error.ts index 3a9cc390aa..c5de62ea0c 100644 --- a/src/Error.ts +++ b/src/Error.ts @@ -18,7 +18,7 @@ type StripeRawError = { doc_url?: string; decline_code?: string; param?: string; - detail?: any; + detail?: string; charge?: string; payment_method_type?: string; @@ -44,7 +44,7 @@ class StripeError extends Error { readonly code?: string; readonly doc_url?: string; readonly param?: string; - readonly detail?: any; + readonly detail?: string; readonly statusCode?: number; readonly charge?: string; readonly decline_code?: string; diff --git a/src/Webhooks.ts b/src/Webhooks.ts index 0d3a7683e2..61cd0b5167 100644 --- a/src/Webhooks.ts +++ b/src/Webhooks.ts @@ -171,6 +171,7 @@ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) { if (!details || details.timestamp === -1) { throw new StripeSignatureVerificationError({ message: 'Unable to extract timestamp and signatures from header', + // @ts-expect-error Type '{ decodedHeader: any; decodedPayload: any; }' is not assignable to type 'string'. detail: { decodedHeader, decodedPayload, @@ -181,6 +182,7 @@ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) { if (!details.signatures.length) { throw new StripeSignatureVerificationError({ message: 'No signatures found with expected scheme', + // @ts-expect-error Type '{ decodedHeader: any; decodedPayload: any; }' is not assignable to type 'string'. detail: { decodedHeader, decodedPayload, @@ -212,6 +214,7 @@ function validateComputedSignature( 'No signatures found matching the expected signature for payload.' + ' Are you passing the raw request body you received from Stripe?' + ' https://github.com/stripe/stripe-node#webhook-signing', + // @ts-expect-error Type '{ header: any; payload: any; }' is not assignable to type 'string'. detail: { header, payload, @@ -224,6 +227,7 @@ function validateComputedSignature( if (tolerance > 0 && timestampAge > tolerance) { throw new StripeSignatureVerificationError({ message: 'Timestamp outside the tolerance zone', + // @ts-expect-error detail: { header, payload, diff --git a/src/utils.ts b/src/utils.ts index 1a75f72732..9741d965f0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -223,6 +223,7 @@ const utils = { * Provide simple "Class" extension mechanism */ protoExtend(sub) { + // eslint-disable-next-line @typescript-eslint/no-this-alias const Super = this; const Constructor = hasOwn(sub, 'constructor') ? sub.constructor diff --git a/yarn.lock b/yarn.lock index 7c7a6481f3..69574b9236 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2395,10 +2395,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^3.7.2: - version "3.9.9" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674" - integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w== +typescript@^3.9.0: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== uri-js@^4.2.2: version "4.4.1" From 818bfc2b88b22fdf1afd0f8cac4fd6970a770dc3 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Mon, 26 Sep 2022 12:38:46 -0700 Subject: [PATCH 03/12] Update TypeScript --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2a1c8f91d7..5dd537c668 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node-fetch": "^2.6.2", "nyc": "^15.1.0", "prettier": "^1.16.4", - "typescript": "^3.9.0" + "typescript": "^4.0.0" }, "resolutions": { "ansi-regex": "5.0.1", diff --git a/yarn.lock b/yarn.lock index 69574b9236..72f44410b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2395,10 +2395,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^3.9.0: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== +typescript@^4.0.0: + version "4.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" + integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== uri-js@^4.2.2: version "4.4.1" From e3a86ffc67d9e8d23264aae65fc6209bf486544e Mon Sep 17 00:00:00 2001 From: Annie Li Date: Mon, 26 Sep 2022 19:54:12 -0700 Subject: [PATCH 04/12] Reviewer comments --- lib/Webhooks.js | 2 +- package.json | 2 +- src/Webhooks.ts | 2 +- src/net/FetchHttpClient.ts | 7 +++++-- src/net/HttpClient.ts | 2 +- src/net/NodeHttpClient.ts | 6 +++--- src/utils.ts | 6 +++--- yarn.lock | 2 +- 8 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/Webhooks.js b/lib/Webhooks.js index fd6a0504fd..f7570b3946 100644 --- a/lib/Webhooks.js +++ b/lib/Webhooks.js @@ -194,7 +194,7 @@ function validateComputedSignature( if (tolerance > 0 && timestampAge > tolerance) { throw new StripeSignatureVerificationError({ message: 'Timestamp outside the tolerance zone', - // @ts-expect-error + // @ts-expect-error Type '{ header: any; payload: any; }' is not assignable to type 'string'. detail: { header, payload, diff --git a/package.json b/package.json index 5dd537c668..82e2f7dc33 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node-fetch": "^2.6.2", "nyc": "^15.1.0", "prettier": "^1.16.4", - "typescript": "^4.0.0" + "typescript": "^4.8.3" }, "resolutions": { "ansi-regex": "5.0.1", diff --git a/src/Webhooks.ts b/src/Webhooks.ts index 61cd0b5167..240e062d35 100644 --- a/src/Webhooks.ts +++ b/src/Webhooks.ts @@ -227,7 +227,7 @@ function validateComputedSignature( if (tolerance > 0 && timestampAge > tolerance) { throw new StripeSignatureVerificationError({ message: 'Timestamp outside the tolerance zone', - // @ts-expect-error + // @ts-expect-error Type '{ header: any; payload: any; }' is not assignable to type 'string'. detail: { header, payload, diff --git a/src/net/FetchHttpClient.ts b/src/net/FetchHttpClient.ts index 3a21ba10f1..7208b8dc65 100644 --- a/src/net/FetchHttpClient.ts +++ b/src/net/FetchHttpClient.ts @@ -12,8 +12,11 @@ const {HttpClient, HttpClientResponse} = _HttpClient; * node-fetch package (https://github.com/node-fetch/node-fetch). */ class FetchHttpClient extends HttpClient { - _fetchFn: any; - _res: any; + _fetchFn: ( + input: RequestInfo | URL, + init?: RequestInit | undefined + ) => Promise; + _res: Response; constructor(fetchFn) { super(); diff --git a/src/net/HttpClient.ts b/src/net/HttpClient.ts index 3c5baefbc3..15d93d5d51 100644 --- a/src/net/HttpClient.ts +++ b/src/net/HttpClient.ts @@ -48,7 +48,7 @@ HttpClient.TIMEOUT_ERROR_CODE = 'ETIMEDOUT'; class HttpClientResponse { _statusCode: number; - _headers: object; + _headers: Record; constructor(statusCode, headers) { this._statusCode = statusCode; diff --git a/src/net/NodeHttpClient.ts b/src/net/NodeHttpClient.ts index f34358f748..f58d899aa3 100644 --- a/src/net/NodeHttpClient.ts +++ b/src/net/NodeHttpClient.ts @@ -1,7 +1,7 @@ 'use strict'; -const http = require('http'); -const https = require('https'); +import http = require('http'); +import https = require('https'); import _HttpClient = require('./HttpClient'); const {HttpClient, HttpClientResponse} = _HttpClient; @@ -14,7 +14,7 @@ const defaultHttpsAgent = new https.Agent({keepAlive: true}); * requests.` */ class NodeHttpClient extends HttpClient { - _agent: any; + _agent: http.Agent | https.Agent; constructor(agent) { super(); diff --git a/src/utils.ts b/src/utils.ts index 9741d965f0..11461eb4b5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -43,11 +43,11 @@ type Settings = { }; type Options = { - auth?: any; - host?: any; + auth?: string; + host?: string; settings?: Settings; streaming?: boolean; - headers?: {[header: string]: string}; + headers?: Record; }; const utils = { diff --git a/yarn.lock b/yarn.lock index 72f44410b5..dac05c29fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2395,7 +2395,7 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.0.0: +typescript@^4.8.3: version "4.8.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== From 651024f710af712779dd95965a51e16f857dd230 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Tue, 27 Sep 2022 09:51:21 -0700 Subject: [PATCH 05/12] Remove 'use strict' from migrated files --- lib/ResourceNamespace.js | 1 - src/ResourceNamespace.ts | 2 -- src/Webhooks.ts | 2 -- src/crypto/CryptoProvider.ts | 2 -- src/crypto/NodeCryptoProvider.ts | 2 -- src/crypto/SubtleCryptoProvider.ts | 2 -- src/multipart.ts | 2 -- src/net/FetchHttpClient.ts | 2 -- src/net/HttpClient.ts | 2 -- src/net/NodeHttpClient.ts | 2 -- src/utils.ts | 2 -- 11 files changed, 21 deletions(-) diff --git a/lib/ResourceNamespace.js b/lib/ResourceNamespace.js index 8267a0fa8b..665a5a3e20 100644 --- a/lib/ResourceNamespace.js +++ b/lib/ResourceNamespace.js @@ -1,4 +1,3 @@ -'use strict'; // ResourceNamespace allows you to create nested resources, i.e. `stripe.issuing.cards`. // It also works recursively, so you could do i.e. `stripe.billing.invoicing.pay`. function ResourceNamespace(stripe, resources) { diff --git a/src/ResourceNamespace.ts b/src/ResourceNamespace.ts index 0d76787d81..c4b6c5566d 100644 --- a/src/ResourceNamespace.ts +++ b/src/ResourceNamespace.ts @@ -1,5 +1,3 @@ -'use strict'; - // ResourceNamespace allows you to create nested resources, i.e. `stripe.issuing.cards`. // It also works recursively, so you could do i.e. `stripe.billing.invoicing.pay`. diff --git a/src/Webhooks.ts b/src/Webhooks.ts index 240e062d35..14d5a4ed8f 100644 --- a/src/Webhooks.ts +++ b/src/Webhooks.ts @@ -1,5 +1,3 @@ -'use strict'; - import utils = require('./utils'); import _Error = require('./Error'); const {StripeError, StripeSignatureVerificationError} = _Error; diff --git a/src/crypto/CryptoProvider.ts b/src/crypto/CryptoProvider.ts index f7be333d61..bd7387c886 100644 --- a/src/crypto/CryptoProvider.ts +++ b/src/crypto/CryptoProvider.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Interface encapsulating the various crypto computations used by the library, * allowing pluggable underlying crypto implementations. diff --git a/src/crypto/NodeCryptoProvider.ts b/src/crypto/NodeCryptoProvider.ts index 9963825f47..4521bc9106 100644 --- a/src/crypto/NodeCryptoProvider.ts +++ b/src/crypto/NodeCryptoProvider.ts @@ -1,5 +1,3 @@ -'use strict'; - import crypto = require('crypto'); import CryptoProvider = require('./CryptoProvider'); diff --git a/src/crypto/SubtleCryptoProvider.ts b/src/crypto/SubtleCryptoProvider.ts index 762bbaaf9c..3fe810fd9b 100644 --- a/src/crypto/SubtleCryptoProvider.ts +++ b/src/crypto/SubtleCryptoProvider.ts @@ -1,5 +1,3 @@ -'use strict'; - import CryptoProvider = require('./CryptoProvider'); /** diff --git a/src/multipart.ts b/src/multipart.ts index 328452fdc8..dbb59a8bcf 100644 --- a/src/multipart.ts +++ b/src/multipart.ts @@ -1,5 +1,3 @@ -'use strict'; - import utils = require('./utils'); import _Error = require('./Error'); const {StripeError} = _Error; diff --git a/src/net/FetchHttpClient.ts b/src/net/FetchHttpClient.ts index 7208b8dc65..6df1781d23 100644 --- a/src/net/FetchHttpClient.ts +++ b/src/net/FetchHttpClient.ts @@ -1,5 +1,3 @@ -'use strict'; - import _HttpClient = require('./HttpClient'); const {HttpClient, HttpClientResponse} = _HttpClient; diff --git a/src/net/HttpClient.ts b/src/net/HttpClient.ts index 15d93d5d51..f8d173193e 100644 --- a/src/net/HttpClient.ts +++ b/src/net/HttpClient.ts @@ -1,5 +1,3 @@ -'use strict'; - type TimeoutError = TypeError & {code?: string}; /** diff --git a/src/net/NodeHttpClient.ts b/src/net/NodeHttpClient.ts index f58d899aa3..e1f66879c7 100644 --- a/src/net/NodeHttpClient.ts +++ b/src/net/NodeHttpClient.ts @@ -1,5 +1,3 @@ -'use strict'; - import http = require('http'); import https = require('https'); diff --git a/src/utils.ts b/src/utils.ts index 11461eb4b5..f1bb3041d0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,3 @@ -'use strict'; - const EventEmitter = require('events').EventEmitter; const qs = require('qs'); const crypto = require('crypto'); From bd502468ed69420821ff29131267f26875bd70fd Mon Sep 17 00:00:00 2001 From: Annie Li Date: Tue, 27 Sep 2022 11:51:01 -0700 Subject: [PATCH 06/12] Turn on alwaysStrict in tsconfig --- lib/ResourceNamespace.js | 1 + lib/apiVersion.js | 1 + tsconfig.json | 1 + 3 files changed, 3 insertions(+) diff --git a/lib/ResourceNamespace.js b/lib/ResourceNamespace.js index 665a5a3e20..8267a0fa8b 100644 --- a/lib/ResourceNamespace.js +++ b/lib/ResourceNamespace.js @@ -1,3 +1,4 @@ +'use strict'; // ResourceNamespace allows you to create nested resources, i.e. `stripe.issuing.cards`. // It also works recursively, so you could do i.e. `stripe.billing.invoicing.pay`. function ResourceNamespace(stripe, resources) { diff --git a/lib/apiVersion.js b/lib/apiVersion.js index 9c1e0e38d1..518f4476ab 100644 --- a/lib/apiVersion.js +++ b/lib/apiVersion.js @@ -1,2 +1,3 @@ +'use strict'; // File generated from our OpenAPI spec module.exports = {ApiVersion: '2022-08-01'}; diff --git a/tsconfig.json b/tsconfig.json index f5cc13096a..199458365d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "target": "es2017", "module": "commonjs", "checkJs": false, + "alwaysStrict": true, }, "include": ["./src/**/*"] } From 98a9b5cdee1ae66c152423a9d58dfe2fc420d078 Mon Sep 17 00:00:00 2001 From: anniel-stripe <97691964+anniel-stripe@users.noreply.github.com> Date: Tue, 27 Sep 2022 12:15:37 -0700 Subject: [PATCH 07/12] Update src/net/NodeHttpClient.ts Co-authored-by: Kamil Pajdzik <99290280+kamil-stripe@users.noreply.github.com> --- src/net/NodeHttpClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/NodeHttpClient.ts b/src/net/NodeHttpClient.ts index e1f66879c7..00c578f88a 100644 --- a/src/net/NodeHttpClient.ts +++ b/src/net/NodeHttpClient.ts @@ -87,7 +87,7 @@ class NodeHttpClient extends HttpClient { } class NodeHttpClientResponse extends HttpClientResponse { - _res: any; + _res: Response; constructor(res) { super(res.statusCode, res.headers || {}); From cc86ba582d6a613ce8bc78152ff3492603350037 Mon Sep 17 00:00:00 2001 From: anniel-stripe <97691964+anniel-stripe@users.noreply.github.com> Date: Tue, 27 Sep 2022 12:16:13 -0700 Subject: [PATCH 08/12] Update src/crypto/SubtleCryptoProvider.ts Co-authored-by: Kamil Pajdzik <99290280+kamil-stripe@users.noreply.github.com> --- src/crypto/SubtleCryptoProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/SubtleCryptoProvider.ts b/src/crypto/SubtleCryptoProvider.ts index 3fe810fd9b..4127c2d463 100644 --- a/src/crypto/SubtleCryptoProvider.ts +++ b/src/crypto/SubtleCryptoProvider.ts @@ -6,7 +6,7 @@ import CryptoProvider = require('./CryptoProvider'); * This only supports asynchronous operations. */ class SubtleCryptoProvider extends CryptoProvider { - subtleCrypto: any; + subtleCrypto: Crypto; constructor(subtleCrypto) { super(); From 9ce094a540fd0c343bd865a31d7c2625d5d2c01d Mon Sep 17 00:00:00 2001 From: anniel-stripe <97691964+anniel-stripe@users.noreply.github.com> Date: Tue, 27 Sep 2022 12:16:21 -0700 Subject: [PATCH 09/12] Update src/crypto/SubtleCryptoProvider.ts Co-authored-by: Kamil Pajdzik <99290280+kamil-stripe@users.noreply.github.com> --- src/crypto/SubtleCryptoProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/SubtleCryptoProvider.ts b/src/crypto/SubtleCryptoProvider.ts index 4127c2d463..4bb9d675ff 100644 --- a/src/crypto/SubtleCryptoProvider.ts +++ b/src/crypto/SubtleCryptoProvider.ts @@ -25,7 +25,7 @@ class SubtleCryptoProvider extends CryptoProvider { } /** @override */ - async computeHMACSignatureAsync(payload, secret) { + async computeHMACSignatureAsync(payload, secret): Promise { const encoder = new TextEncoder(); const key = await this.subtleCrypto.importKey( From a2526b221f34ba4b461af055b01b11d7bed1bf95 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Tue, 27 Sep 2022 12:32:10 -0700 Subject: [PATCH 10/12] Remove hasOwn alias, undo suggested commits --- lib/utils.js | 16 +++++++++++----- src/crypto/SubtleCryptoProvider.ts | 2 +- src/net/NodeHttpClient.ts | 2 +- src/utils.ts | 17 +++++++++++------ 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/utils.js b/lib/utils.js index c1b48eb913..a17afff790 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -2,7 +2,6 @@ const EventEmitter = require('events').EventEmitter; const qs = require('qs'); const crypto = require('crypto'); -const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); // Certain sandboxed environments (our known example right now are CloudFlare // Workers) may make `child_process` unavailable. Because `exec` isn't critical // to the operation of stripe-node, we handle this unavailability gracefully. @@ -36,8 +35,12 @@ const utils = { return ( o && typeof o === 'object' && - (OPTIONS_KEYS.some((prop) => hasOwn(o, prop)) || - DEPRECATED_OPTIONS_KEYS.some((prop) => hasOwn(o, prop))) + (OPTIONS_KEYS.some((prop) => + Object.prototype.hasOwnProperty.call(o, prop) + ) || + DEPRECATED_OPTIONS_KEYS.some((prop) => + Object.prototype.hasOwnProperty.call(o, prop) + )) ); }, /** @@ -191,7 +194,7 @@ const utils = { protoExtend(sub) { // eslint-disable-next-line @typescript-eslint/no-this-alias const Super = this; - const Constructor = hasOwn(sub, 'constructor') + const Constructor = Object.prototype.hasOwnProperty.call(sub, 'constructor') ? sub.constructor : function(...args) { Super.apply(this, args); @@ -343,7 +346,10 @@ const utils = { const value = obj[key]; const newKey = prevKey ? `${prevKey}[${key}]` : key; if (utils.isObject(value)) { - if (!Buffer.isBuffer(value) && !hasOwn(value, 'data')) { + if ( + !Buffer.isBuffer(value) && + !Object.prototype.hasOwnProperty.call(value, 'data') + ) { // Non-buffer non-file Objects are recursively flattened return step(value, newKey); } else { diff --git a/src/crypto/SubtleCryptoProvider.ts b/src/crypto/SubtleCryptoProvider.ts index 4bb9d675ff..cfdf61eedc 100644 --- a/src/crypto/SubtleCryptoProvider.ts +++ b/src/crypto/SubtleCryptoProvider.ts @@ -6,7 +6,7 @@ import CryptoProvider = require('./CryptoProvider'); * This only supports asynchronous operations. */ class SubtleCryptoProvider extends CryptoProvider { - subtleCrypto: Crypto; + subtleCrypto: any; constructor(subtleCrypto) { super(); diff --git a/src/net/NodeHttpClient.ts b/src/net/NodeHttpClient.ts index 00c578f88a..e1f66879c7 100644 --- a/src/net/NodeHttpClient.ts +++ b/src/net/NodeHttpClient.ts @@ -87,7 +87,7 @@ class NodeHttpClient extends HttpClient { } class NodeHttpClientResponse extends HttpClientResponse { - _res: Response; + _res: any; constructor(res) { super(res.statusCode, res.headers || {}); diff --git a/src/utils.ts b/src/utils.ts index f1bb3041d0..b3ac274cbc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,8 +2,6 @@ const EventEmitter = require('events').EventEmitter; const qs = require('qs'); const crypto = require('crypto'); -const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); - // Certain sandboxed environments (our known example right now are CloudFlare // Workers) may make `child_process` unavailable. Because `exec` isn't critical // to the operation of stripe-node, we handle this unavailability gracefully. @@ -53,8 +51,12 @@ const utils = { return ( o && typeof o === 'object' && - (OPTIONS_KEYS.some((prop) => hasOwn(o, prop)) || - DEPRECATED_OPTIONS_KEYS.some((prop) => hasOwn(o, prop))) + (OPTIONS_KEYS.some((prop) => + Object.prototype.hasOwnProperty.call(o, prop) + ) || + DEPRECATED_OPTIONS_KEYS.some((prop) => + Object.prototype.hasOwnProperty.call(o, prop) + )) ); }, @@ -223,7 +225,7 @@ const utils = { protoExtend(sub) { // eslint-disable-next-line @typescript-eslint/no-this-alias const Super = this; - const Constructor = hasOwn(sub, 'constructor') + const Constructor = Object.prototype.hasOwnProperty.call(sub, 'constructor') ? sub.constructor : function(...args) { Super.apply(this, args); @@ -400,7 +402,10 @@ const utils = { const newKey = prevKey ? `${prevKey}[${key}]` : key; if (utils.isObject(value)) { - if (!Buffer.isBuffer(value) && !hasOwn(value, 'data')) { + if ( + !Buffer.isBuffer(value) && + !Object.prototype.hasOwnProperty.call(value, 'data') + ) { // Non-buffer non-file Objects are recursively flattened return step(value, newKey); } else { From 2704e87c4b3784e2283d4c9900f8feb97f37b938 Mon Sep 17 00:00:00 2001 From: anniel-stripe <97691964+anniel-stripe@users.noreply.github.com> Date: Tue, 27 Sep 2022 12:38:25 -0700 Subject: [PATCH 11/12] Update src/net/FetchHttpClient.ts Co-authored-by: Kamil Pajdzik <99290280+kamil-stripe@users.noreply.github.com> --- src/net/FetchHttpClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/FetchHttpClient.ts b/src/net/FetchHttpClient.ts index 6df1781d23..630bddc42d 100644 --- a/src/net/FetchHttpClient.ts +++ b/src/net/FetchHttpClient.ts @@ -93,7 +93,7 @@ class FetchHttpClient extends HttpClient { } class FetchHttpClientResponse extends HttpClientResponse { - _res: any; + _res: Response; constructor(res) { super( From 06a6d4e5f5a89fc87e31b255e05e4bfa18f15913 Mon Sep 17 00:00:00 2001 From: Kamil Pajdzik Date: Tue, 27 Sep 2022 21:45:32 -0700 Subject: [PATCH 12/12] Add more types to HTTP clients --- src/crypto/SubtleCryptoProvider.ts | 9 ++++++--- src/net/HttpClient.ts | 6 +++--- src/net/NodeHttpClient.ts | 6 +++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/crypto/SubtleCryptoProvider.ts b/src/crypto/SubtleCryptoProvider.ts index cfdf61eedc..999181e4cc 100644 --- a/src/crypto/SubtleCryptoProvider.ts +++ b/src/crypto/SubtleCryptoProvider.ts @@ -6,9 +6,9 @@ import CryptoProvider = require('./CryptoProvider'); * This only supports asynchronous operations. */ class SubtleCryptoProvider extends CryptoProvider { - subtleCrypto: any; + subtleCrypto: SubtleCrypto; - constructor(subtleCrypto) { + constructor(subtleCrypto: SubtleCrypto) { super(); // If no subtle crypto is interface, default to the global namespace. This @@ -25,7 +25,10 @@ class SubtleCryptoProvider extends CryptoProvider { } /** @override */ - async computeHMACSignatureAsync(payload, secret): Promise { + async computeHMACSignatureAsync( + payload: string, + secret: string + ): Promise { const encoder = new TextEncoder(); const key = await this.subtleCrypto.importKey( diff --git a/src/net/HttpClient.ts b/src/net/HttpClient.ts index f8d173193e..2c035d7cd7 100644 --- a/src/net/HttpClient.ts +++ b/src/net/HttpClient.ts @@ -53,11 +53,11 @@ class HttpClientResponse { this._headers = headers; } - getStatusCode() { + getStatusCode(): number { return this._statusCode; } - getHeaders() { + getHeaders(): Record { return this._headers; } @@ -69,7 +69,7 @@ class HttpClientResponse { throw new Error('toStream not implemented.'); } - toJSON() { + toJSON(): any { throw new Error('toJSON not implemented.'); } } diff --git a/src/net/NodeHttpClient.ts b/src/net/NodeHttpClient.ts index e1f66879c7..1d556a0906 100644 --- a/src/net/NodeHttpClient.ts +++ b/src/net/NodeHttpClient.ts @@ -87,9 +87,9 @@ class NodeHttpClient extends HttpClient { } class NodeHttpClientResponse extends HttpClientResponse { - _res: any; + _res: http.IncomingMessage; - constructor(res) { + constructor(res: http.IncomingMessage) { super(res.statusCode, res.headers || {}); this._res = res; } @@ -106,7 +106,7 @@ class NodeHttpClientResponse extends HttpClientResponse { return this._res; } - toJSON() { + toJSON(): any { return new Promise((resolve, reject) => { let response = '';