Repository: stripe/stripe-node
Pull request #1687 (2023-02-22 22:23:12)

Convert TypeScript files to use ES modules
## Summary
This PR updates our TypeScript source files to use ESM syntax to get better type safety. I opted to use named exports in our internal files to make it more obvious what is being exported / imported. This also updates CJS imports (`require(...)`) as needed in generated resource files and tests to use those named exports.

## Testing
Functionality of transpiled output (in `lib/`) should stay the same. Verified in manual test projects that named and default exports still work when `stripe` is imported using `import` or `require`.


Patch:
diff --git a/lib/Error.js b/lib/Error.js
index 68d6a0b5..e6f17b66 100644
--- a/lib/Error.js
+++ b/lib/Error.js
@@ -1,5 +1,28 @@
 "use strict";
 /* eslint-disable camelcase */
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.StripeUnknownError = exports.StripeInvalidGrantError = exports.StripeIdempotencyError = exports.StripeSignatureVerificationError = exports.StripeConnectionError = exports.StripeRateLimitError = exports.StripePermissionError = exports.StripeAuthenticationError = exports.StripeAPIError = exports.StripeInvalidRequestError = exports.StripeCardError = exports.StripeError = exports.generate = void 0;
+const generate = (rawStripeError) => {
+    switch (rawStripeError.type) {
+        case 'card_error':
+            return new StripeCardError(rawStripeError);
+        case 'invalid_request_error':
+            return new StripeInvalidRequestError(rawStripeError);
+        case 'api_error':
+            return new StripeAPIError(rawStripeError);
+        case 'authentication_error':
+            return new StripeAuthenticationError(rawStripeError);
+        case 'rate_limit_error':
+            return new StripeRateLimitError(rawStripeError);
+        case 'idempotency_error':
+            return new StripeIdempotencyError(rawStripeError);
+        case 'invalid_grant':
+            return new StripeInvalidGrantError(rawStripeError);
+        default:
+            return new StripeUnknownError(rawStripeError);
+    }
+};
+exports.generate = generate;
 /**
  * StripeError is the base error from which all other more specific Stripe errors derive.
  * Specifically for errors returned from Stripe's REST API.
@@ -27,30 +50,12 @@ class StripeError extends Error {
         this.setup_intent = raw.setup_intent;
         this.source = raw.source;
     }
-    /**
-     * Helper factory which takes raw stripe errors and outputs wrapping instances
-     */
-    static generate(rawStripeError) {
-        switch (rawStripeError.type) {
-            case 'card_error':
-                return new StripeCardError(rawStripeError);
-            case 'invalid_request_error':
-                return new StripeInvalidRequestError(rawStripeError);
-            case 'api_error':
-                return new StripeAPIError(rawStripeError);
-            case 'authentication_error':
-                return new StripeAuthenticationError(rawStripeError);
-            case 'rate_limit_error':
-                return new StripeRateLimitError(rawStripeError);
-            case 'idempotency_error':
-                return new StripeIdempotencyError(rawStripeError);
-            case 'invalid_grant':
-                return new StripeInvalidGrantError(rawStripeError);
-            default:
-                return new StripeUnknownError(rawStripeError);
-        }
-    }
 }
+exports.StripeError = StripeError;
+/**
+ * Helper factory which takes raw stripe errors and outputs wrapping instances
+ */
+StripeError.generate = exports.generate;
 // Specific Stripe Error types:
 /**
  * CardError is raised when a user enters a card that can't be charged for
@@ -58,12 +63,14 @@ class StripeError extends Error {
  */
 class StripeCardError extends StripeError {
 }
+exports.StripeCardError = StripeCardError;
 /**
  * InvalidRequestError is raised when a request is initiated with invalid
  * parameters.
  */
 class StripeInvalidRequestError extends StripeError {
 }
+exports.StripeInvalidRequestError = StripeInvalidRequestError;
 /**
  * APIError is a generic error that may be raised in cases where none of the
  * other named errors cover the problem. It could also be raised in the case
@@ -72,18 +79,21 @@ class StripeInvalidRequestError extends StripeError {
  */
 class StripeAPIError extends StripeError {
 }
+exports.StripeAPIError = StripeAPIError;
 /**
  * AuthenticationError is raised when invalid credentials are used to connect
  * to Stripe's servers.
  */
 class StripeAuthenticationError extends StripeError {
 }
+exports.StripeAuthenticationError = StripeAuthenticationError;
 /**
  * PermissionError is raised in cases where access was attempted on a resource
  * that wasn't allowed.
  */
 class StripePermissionError extends StripeError {
 }
+exports.StripePermissionError = StripePermissionError;
 /**
  * RateLimitError is raised in cases where an account is putting too much load
  * on Stripe's API servers (usually by performing too many requests). Please
@@ -91,6 +101,7 @@ class StripePermissionError extends StripeError {
  */
 class StripeRateLimitError extends StripeError {
 }
+exports.StripeRateLimitError = StripeRateLimitError;
 /**
  * StripeConnectionError is raised in the event that the SDK can't connect to
  * Stripe's servers. That can be for a variety of different reasons from a
@@ -98,6 +109,7 @@ class StripeRateLimitError extends StripeError {
  */
 class StripeConnectionError extends StripeError {
 }
+exports.StripeConnectionError = StripeConnectionError;
 /**
  * SignatureVerificationError is raised when the signature verification for a
  * webhook fails
@@ -109,12 +121,14 @@ class StripeSignatureVerificationError extends StripeError {
         this.payload = payload;
     }
 }
+exports.StripeSignatureVerificationError = StripeSignatureVerificationError;
 /**
  * IdempotencyError is raised in cases where an idempotency key was used
  * improperly.
  */
 class StripeIdempotencyError extends StripeError {
 }
+exports.StripeIdempotencyError = StripeIdempotencyError;
 /**
  * InvalidGrantError is raised when a specified code doesn't exist, is
  * expired, has been used, or doesn't belong to you; a refresh token doesn't
@@ -123,23 +137,10 @@ class StripeIdempotencyError extends StripeError {
  */
 class StripeInvalidGrantError extends StripeError {
 }
+exports.StripeInvalidGrantError = StripeInvalidGrantError;
 /**
  * Any other error from Stripe not specifically captured above
  */
 class StripeUnknownError extends StripeError {
 }
-module.exports = {
-    generate: StripeError.generate,
-    StripeError: StripeError,
-    StripeCardError: StripeCardError,
-    StripeInvalidRequestError: StripeInvalidRequestError,
-    StripeAPIError: StripeAPIError,
-    StripeAuthenticationError: StripeAuthenticationError,
-    StripePermissionError: StripePermissionError,
-    StripeRateLimitError: StripeRateLimitError,
-    StripeConnectionError: StripeConnectionError,
-    StripeSignatureVerificationError: StripeSignatureVerificationError,
-    StripeIdempotencyError: StripeIdempotencyError,
-    StripeInvalidGrantError: StripeInvalidGrantError,
-    StripeUnknownError: StripeUnknownError,
-};
+exports.StripeUnknownError = StripeUnknownError;
diff --git a/lib/RequestSender.js b/lib/RequestSender.js
index 05130b3a..670c0090 100644
--- a/lib/RequestSender.js
+++ b/lib/RequestSender.js
@@ -1,8 +1,9 @@
 "use strict";
-const _Error = require("./Error");
-const utils = require("./utils");
-const { StripeAPIError, StripeAuthenticationError, StripeConnectionError, StripeError, StripePermissionError, StripeRateLimitError, } = _Error;
-const { HttpClient } = require('./net/HttpClient');
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RequestSender = void 0;
+const Error_1 = require("./Error");
+const utils_1 = require("./utils");
+const HttpClient_1 = require("./net/HttpClient");
 const MAX_RETRY_AFTER_WAIT = 60;
 class RequestSender {
     constructor(stripe, maxBufferedRequestMetric) {
@@ -21,7 +22,7 @@ class RequestSender {
     _makeResponseEvent(requestEvent, statusCode, headers) {
         const requestEndTime = Date.now();
         const requestDurationMs = requestEndTime - requestEvent.request_start_time;
-        return utils.removeNullish({
+        return (0, utils_1.removeNullish)({
             api_version: headers['stripe-version'],
             account: headers['stripe-account'],
             idempotency_key: headers['idempotency-key'],
@@ -92,22 +93,22 @@ class RequestSender {
                     jsonResponse.error.statusCode = statusCode;
                     jsonResponse.error.requestId = requestId;
                     if (statusCode === 401) {
-                        err = new StripeAuthenticationError(jsonResponse.error);
+                        err = new Error_1.StripeAuthenticationError(jsonResponse.error);
                     }
                     else if (statusCode === 403) {
-                        err = new StripePermissionError(jsonResponse.error);
+                        err = new Error_1.StripePermissionError(jsonResponse.error);
                     }
                     else if (statusCode === 429) {
-                        err = new StripeRateLimitError(jsonResponse.error);
+                        err = new Error_1.StripeRateLimitError(jsonResponse.error);
                     }
                     else {
-                        err = StripeError.generate(jsonResponse.error);
+                        err = Error_1.StripeError.generate(jsonResponse.error);
                     }
                     throw err;
                 }
                 return jsonResponse;
             }, (e) => {
-                throw new StripeAPIError({
+                throw new Error_1.StripeAPIError({
                     message: 'Invalid JSON received from the Stripe API',
                     exception: e,
                     requestId: headers['request-id'],
@@ -134,7 +135,7 @@ class RequestSender {
     static _shouldRetry(res, numRetries, maxRetries, error) {
         if (error &&
             numRetries === 0 &&
-            HttpClient.CONNECTION_CLOSED_ERROR_CODES.includes(error.code)) {
+            HttpClient_1.HttpClient.CONNECTION_CLOSED_ERROR_CODES.includes(error.code)) {
             return true;
         }
         // Do not retry if we are out of retries.
@@ -232,13 +233,13 @@ class RequestSender {
         // and fix these cases as they are semantically incorrect.
         if (methodHasPayload || contentLength) {
             if (!methodHasPayload) {
-                utils.emitWarning(`${method} method had non-zero contentLength but no payload is expected for this verb`);
+                (0, utils_1.emitWarning)(`${method} method had non-zero contentLength but no payload is expected for this verb`);
             }
             defaultHeaders['Content-Length'] = contentLength;
         }
-        return Object.assign(utils.removeNullish(defaultHeaders), 
+        return Object.assign((0, utils_1.removeNullish)(defaultHeaders), 
         // If the user supplied, say 'idempotency-key', override instead of appending by ensuring caps are the same.
-        utils.normalizeHeaders(userSuppliedHeaders));
+        (0, utils_1.normalizeHeaders)(userSuppliedHeaders));
     }
     _getUserAgentString() {
         const packageVersion = this._stripe.getConstant('PACKAGE_VERSION');
@@ -259,7 +260,7 @@ class RequestSender {
     _recordRequestMetrics(requestId, requestDurationMs) {
         if (this._stripe.getTelemetryEnabled() && requestId) {
             if (this._stripe._prevRequestMetrics.length > this._maxBufferedRequestMetric) {
-                utils.emitWarning('Request metrics buffer is full, dropping telemetry message.');
+                (0, utils_1.emitWarning)('Request metrics buffer is full, dropping telemetry message.');
             }
             else {
                 this._stripe._prevRequestMetrics.push({
@@ -287,7 +288,7 @@ class RequestSender {
                 .makeRequest(host || this._stripe.getApiField('host'), this._stripe.getApiField('port'), path, method, headers, requestData, this._stripe.getApiField('protocol'), timeout);
             const requestStartTime = Date.now();
             // @ts-ignore
-            const requestEvent = utils.removeNullish({
+            const requestEvent = (0, utils_1.removeNullish)({
                 api_version: apiVersion,
                 account: headers['Stripe-Account'],
                 idempotency_key: headers['Idempotency-Key'],
@@ -317,8 +318,8 @@ class RequestSender {
                     return retryRequest(makeRequest, apiVersion, headers, requestRetries, null);
                 }
                 else {
-                    const isTimeoutError = error.code && error.code === HttpClient.TIMEOUT_ERROR_CODE;
-                    return callback(new StripeConnectionError({
+                    const isTimeoutError = error.code && error.code === HttpClient_1.HttpClient.TIMEOUT_ERROR_CODE;
+                    return callback(new Error_1.StripeConnectionError({
                         message: isTimeoutError
                             ? `Request aborted due to timeout being reached (${timeout}ms)`
                             : RequestSender._generateConnectionErrorMessage(requestRetries),
@@ -344,8 +345,8 @@ class RequestSender {
             requestDataProcessor(method, data, options.headers, prepareAndMakeRequest);
         }
         else {
-            prepareAndMakeRequest(null, utils.stringifyRequestData(data || {}));
+            prepareAndMakeRequest(null, (0, utils_1.stringifyRequestData)(data || {}));
         }
     }
 }
-module.exports = RequestSender;
+exports.RequestSender = RequestSender;
diff --git a/lib/ResourceNamespace.js b/lib/ResourceNamespace.js
index 5d7f0e7e..d482e115 100644
--- a/lib/ResourceNamespace.js
+++ b/lib/ResourceNamespace.js
@@ -1,4 +1,6 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.resourceNamespace = void 0;
 // 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) {
@@ -8,9 +10,9 @@ function ResourceNamespace(stripe, resources) {
         this[camelCaseName] = resource;
     }
 }
-module.exports = function (namespace, resources) {
+function resourceNamespace(namespace, resources) {
     return function (stripe) {
         return new ResourceNamespace(stripe, resources);
     };
-};
-module.exports.ResourceNamespace = ResourceNamespace;
+}
+exports.resourceNamespace = resourceNamespace;
diff --git a/lib/StripeEmitter.js b/lib/StripeEmitter.js
index 03e5ec95..703b8677 100644
--- a/lib/StripeEmitter.js
+++ b/lib/StripeEmitter.js
@@ -1,4 +1,6 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.StripeEmitter = void 0;
 /**
  * @private
  * (For internal use in stripe-node.)
@@ -41,4 +43,4 @@ class StripeEmitter {
         return this.eventTarget.dispatchEvent(new _StripeEvent(eventName, data));
     }
 }
-module.exports = StripeEmitter;
+exports.StripeEmitter = StripeEmitter;
diff --git a/lib/StripeMethod.js b/lib/StripeMethod.js
index 4dd09228..07bb649c 100644
--- a/lib/StripeMethod.js
+++ b/lib/StripeMethod.js
@@ -1,7 +1,8 @@
 "use strict";
-const utils = require("./utils");
-const autoPagination = require("./autoPagination");
-const makeAutoPaginationMethods = autoPagination.makeAutoPaginationMethods;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.stripeMethod = void 0;
+const utils_1 = require("./utils");
+const autoPagination_1 = require("./autoPagination");
 /**
  * Create an API method from the declared spec.
  *
@@ -17,6 +18,8 @@ const makeAutoPaginationMethods = autoPagination.makeAutoPaginationMethods;
  * @param [spec.encode] Function for mutating input parameters to a method.
  *  Usefully for applying transforms to data on a per-method basis.
  * @param [spec.host] Hostname for the request.
+ *
+ * <!-- Public API accessible via Stripe.StripeResource.method -->
  */
 function stripeMethod(spec) {
     if (spec.path !== undefined && spec.fullPath !== undefined) {
@@ -24,15 +27,15 @@ function stripeMethod(spec) {
     }
     return function (...args) {
         const callback = typeof args[args.length - 1] == 'function' && args.pop();
-        spec.urlParams = utils.extractUrlParams(spec.fullPath || this.createResourcePathWithSymbols(spec.path || ''));
-        const requestPromise = utils.callbackifyPromiseWithTimeout(this._makeRequest(args, spec, {}), callback);
+        spec.urlParams = (0, utils_1.extractUrlParams)(spec.fullPath || this.createResourcePathWithSymbols(spec.path || ''));
+        const requestPromise = (0, utils_1.callbackifyPromiseWithTimeout)(this._makeRequest(args, spec, {}), callback);
         // Please note `spec.methodType === 'search'` is beta functionality and this
         // interface is subject to change/removal at any time.
         if (spec.methodType === 'list' || spec.methodType === 'search') {
-            const autoPaginationMethods = makeAutoPaginationMethods(this, args, spec, requestPromise);
+            const autoPaginationMethods = (0, autoPagination_1.makeAutoPaginationMethods)(this, args, spec, requestPromise);
             Object.assign(requestPromise, autoPaginationMethods);
         }
         return requestPromise;
     };
 }
-module.exports = stripeMethod;
+exports.stripeMethod = stripeMethod;
diff --git a/lib/StripeResource.js b/lib/StripeResource.js
index 8039608d..f247e41d 100644
--- a/lib/StripeResource.js
+++ b/lib/StripeResource.js
@@ -1,9 +1,12 @@
 "use strict";
-const utils = require("./utils");
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.StripeResource = void 0;
+const utils_1 = require("./utils");
+const StripeMethod_1 = require("./StripeMethod");
 // Provide extension mechanism for Stripe Resource Sub-Classes
-StripeResource.extend = utils.protoExtend;
+StripeResource.extend = utils_1.protoExtend;
 // Expose method-creator
-StripeResource.method = require('./StripeMethod');
+StripeResource.method = StripeMethod_1.stripeMethod;
 StripeResource.MAX_BUFFERED_REQUEST_METRICS = 100;
 /**
  * Encapsulates request logic for a Stripe Resource
@@ -13,15 +16,16 @@ function StripeResource(stripe, deprecatedUrlData) {
     if (deprecatedUrlData) {
         throw new Error('Support for curried url params was dropped in stripe-node v7.0.0. Instead, pass two ids.');
     }
-    this.basePath = utils.makeURLInterpolator(
+    this.basePath = (0, utils_1.makeURLInterpolator)(
     // @ts-ignore changing type of basePath
     this.basePath || stripe.getApiField('basePath'));
     // @ts-ignore changing type of path
     this.resourcePath = this.path;
     // @ts-ignore changing type of path
-    this.path = utils.makeURLInterpolator(this.path);
+    this.path = (0, utils_1.makeURLInterpolator)(this.path);
     this.initialize(...arguments);
 }
+exports.StripeResource = StripeResource;
 StripeResource.prototype = {
     _stripe: null,
     // @ts-ignore the type of path changes in ctor
@@ -80,7 +84,7 @@ StripeResource.prototype = {
         const urlParams = spec.urlParams || [];
         const encode = spec.encode || ((data) => data);
         const isUsingFullPath = !!spec.fullPath;
-        const commandPath = utils.makeURLInterpolator(isUsingFullPath ? spec.fullPath : spec.path || '');
+        const commandPath = (0, utils_1.makeURLInterpolator)(isUsingFullPath ? spec.fullPath : spec.path || '');
         // When using fullPath, we ignore the resource path as it should already be
         // fully qualified.
         const path = isUsingFullPath
@@ -98,9 +102,9 @@ StripeResource.prototype = {
             return urlData;
         }, {});
         // Pull request data and options (headers, auth) from args.
-        const dataFromArgs = utils.getDataFromArgs(args);
+        const dataFromArgs = (0, utils_1.getDataFromArgs)(args);
         const data = encode(Object.assign({}, dataFromArgs, overrideData));
-        const options = utils.getOptionsFromArgs(args);
+        const options = (0, utils_1.getOptionsFromArgs)(args);
         const host = options.host || spec.host;
         const streaming = !!spec.streaming;
         // Validate that there are no more args.
@@ -156,11 +160,10 @@ StripeResource.prototype = {
             const path = [
                 opts.requestPath,
                 emptyQuery ? '' : '?',
-                utils.stringifyRequestData(opts.queryData),
+                (0, utils_1.stringifyRequestData)(opts.queryData),
             ].join('');
             const { headers, settings } = opts;
             this._stripe._requestSender._request(opts.requestMethod, opts.host, path, opts.bodyData, opts.auth, { headers, settings, streaming: opts.streaming }, requestCallback, (_a = this.requestDataProcessor) === null || _a === void 0 ? void 0 : _a.bind(this));
         });
     },
 };
-module.exports = StripeResource;
diff --git a/lib/Webhooks.js b/lib/Webhooks.js
index 13ddb5c0..65bb6707 100644
--- a/lib/Webhooks.js
+++ b/lib/Webhooks.js
@@ -1,6 +1,7 @@
 "use strict";
-const _Error = require("./Error");
-const { StripeError, StripeSignatureVerificationError } = _Error;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createWebhooks = void 0;
+const Error_1 = require("./Error");
 function createWebhooks(platformFunctions) {
     const Webhook = {
         DEFAULT_TOLERANCE: 300,
@@ -33,7 +34,7 @@ function createWebhooks(platformFunctions) {
          */
         generateTestHeaderString: function (opts) {
             if (!opts) {
-                throw new StripeError({
+                throw new Error_1.StripeError({
                     message: 'Options are required',
                 });
             }
@@ -72,7 +73,7 @@ function createWebhooks(platformFunctions) {
     }
     function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) {
         if (!encodedPayload) {
-            throw new StripeSignatureVerificationError(encodedHeader, encodedPayload, {
+            throw new Error_1.StripeSignatureVerificationError(encodedHeader, encodedPayload, {
                 message: 'No webhook payload was provided.',
             });
         }
@@ -90,7 +91,7 @@ function createWebhooks(platformFunctions) {
             throw new Error('Unexpected: An array was passed as a header, which should not be possible for the stripe-signature header.');
         }
         if (encodedHeader == null || encodedHeader == '') {
-            throw new StripeSignatureVerificationError(encodedHeader, encodedPayload, {
+            throw new Error_1.StripeSignatureVerificationError(encodedHeader, encodedPayload, {
                 message: 'No stripe-signature header value was provided.',
             });
         }
@@ -99,12 +100,12 @@ function createWebhooks(platformFunctions) {
             : encodedHeader;
         const details = parseHeader(decodedHeader, expectedScheme);
         if (!details || details.timestamp === -1) {
-            throw new StripeSignatureVerificationError(decodedHeader, decodedPayload, {
+            throw new Error_1.StripeSignatureVerificationError(decodedHeader, decodedPayload, {
                 message: 'Unable to extract timestamp and signatures from header',
             });
         }
         if (!details.signatures.length) {
-            throw new StripeSignatureVerificationError(decodedHeader, decodedPayload, {
+            throw new Error_1.StripeSignatureVerificationError(decodedHeader, decodedPayload, {
                 message: 'No signatures found with expected scheme',
             });
         }
@@ -119,7 +120,7 @@ function createWebhooks(platformFunctions) {
         const signatureFound = !!details.signatures.filter(platformFunctions.secureCompare.bind(platformFunctions, expectedSignature)).length;
         if (!signatureFound) {
             if (suspectPayloadType) {
-                throw new StripeSignatureVerificationError(header, payload, {
+                throw new Error_1.StripeSignatureVerificationError(header, payload, {
                     message: 'Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the _raw_ request body.' +
                         'Payload was provided as a parsed JavaScript object instead. \n' +
                         'Signature verification is impossible without access to the original signed material. \n' +
@@ -127,7 +128,7 @@ function createWebhooks(platformFunctions) {
                         'https://github.com/stripe/stripe-node#webhook-signing',
                 });
             }
-            throw new StripeSignatureVerificationError(header, payload, {
+            throw new Error_1.StripeSignatureVerificationError(header, payload, {
                 message: 'No signatures found matching the expected signature for payload.' +
                     ' Are you passing the raw request body you received from Stripe? \n' +
                     'Learn more about webhook signing and explore webhook integration examples for various frameworks at ' +
@@ -137,7 +138,7 @@ function createWebhooks(platformFunctions) {
         const timestampAge = Math.floor(Date.now() / 1000) - details.timestamp;
         if (tolerance > 0 && timestampAge > tolerance) {
             // @ts-ignore
-            throw new StripeSignatureVerificationError(header, payload, {
+            throw new Error_1.StripeSignatureVerificationError(header, payload, {
                 message: 'Timestamp outside the tolerance zone',
             });
         }
@@ -175,4 +176,4 @@ function createWebhooks(platformFunctions) {
     Webhook.signature = signature;
     return Webhook;
 }
-module.exports = createWebhooks;
+exports.createWebhooks = createWebhooks;
diff --git a/lib/autoPagination.js b/lib/autoPagination.js
index 929834c1..05c86409 100644
--- a/lib/autoPagination.js
+++ b/lib/autoPagination.js
@@ -1,5 +1,7 @@
 "use strict";
-const utils = require("./utils");
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.makeAutoPaginationMethods = void 0;
+const utils_1 = require("./utils");
 function makeAutoPaginationMethods(self, requestArgs, spec, firstPagePromise) {
     const promiseCache = { currentPromise: null };
     const reverseIteration = isReverseIteration(requestArgs);
@@ -76,6 +78,7 @@ function makeAutoPaginationMethods(self, requestArgs, spec, firstPagePromise) {
     };
     return autoPaginationMethods;
 }
+exports.makeAutoPaginationMethods = makeAutoPaginationMethods;
 /**
  * ----------------
  * Private Helpers:
@@ -168,7 +171,7 @@ function makeAutoPagingEach(asyncIteratorNext) {
         const autoPagePromise = wrapAsyncIteratorWithCallback(asyncIteratorNext, 
         // @ts-ignore we might need a null check
         onItem);
-        return utils.callbackifyPromiseWithTimeout(autoPagePromise, onDone);
+        return (0, utils_1.callbackifyPromiseWithTimeout)(autoPagePromise, onDone);
     };
 }
 function makeAutoPagingToArray(autoPagingEach) {
@@ -194,7 +197,7 @@ function makeAutoPagingToArray(autoPagingEach) {
                 .catch(reject);
         });
         // @ts-ignore
-        return utils.callbackifyPromiseWithTimeout(promise, onDone);
+        return (0, utils_1.callbackifyPromiseWithTimeout)(promise, onDone);
     };
 }
 function wrapAsyncIteratorWithCallback(asyncIteratorNext, onItem) {
@@ -226,9 +229,6 @@ function wrapAsyncIteratorWithCallback(asyncIteratorNext, onItem) {
 }
 function isReverseIteration(requestArgs) {
     const args = [].slice.call(requestArgs);
-    const dataFromArgs = utils.getDataFromArgs(args);
+    const dataFromArgs = (0, utils_1.getDataFromArgs)(args);
     return !!dataFromArgs.ending_before;
 }
-module.exports = {
-    makeAutoPaginationMethods: makeAutoPaginationMethods,
-};
diff --git a/lib/crypto/CryptoProvider.js b/lib/crypto/CryptoProvider.js
index 4491a017..560ceede 100644
--- a/lib/crypto/CryptoProvider.js
+++ b/lib/crypto/CryptoProvider.js
@@ -1,4 +1,6 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.CryptoProvider = void 0;
 /**
  * Interface encapsulating the various crypto computations used by the library,
  * allowing pluggable underlying crypto implementations.
@@ -30,4 +32,4 @@ class CryptoProvider {
         throw new Error('computeHMACSignatureAsync not implemented.');
     }
 }
-module.exports = CryptoProvider;
+exports.CryptoProvider = CryptoProvider;
diff --git a/lib/crypto/NodeCryptoProvider.js b/lib/crypto/NodeCryptoProvider.js
index 95acdd2b..88cbd019 100644
--- a/lib/crypto/NodeCryptoProvider.js
+++ b/lib/crypto/NodeCryptoProvider.js
@@ -1,10 +1,12 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.NodeCryptoProvider = void 0;
 const crypto = require("crypto");
-const CryptoProvider = require("./CryptoProvider");
+const CryptoProvider_1 = require("./CryptoProvider");
 /**
  * `CryptoProvider which uses the Node `crypto` package for its computations.
  */
-class NodeCryptoProvider extends CryptoProvider {
+class NodeCryptoProvider extends CryptoProvider_1.CryptoProvider {
     /** @override */
     computeHMACSignature(payload, secret) {
         return crypto
@@ -18,4 +20,4 @@ class NodeCryptoProvider extends CryptoProvider {
         return signature;
     }
 }
-module.exports = NodeCryptoProvider;
+exports.NodeCryptoProvider = NodeCryptoProvider;
diff --git a/lib/crypto/SubtleCryptoProvider.js b/lib/crypto/SubtleCryptoProvider.js
index 8f23b3bc..3fbf5cf4 100644
--- a/lib/crypto/SubtleCryptoProvider.js
+++ b/lib/crypto/SubtleCryptoProvider.js
@@ -1,11 +1,13 @@
 "use strict";
-const CryptoProvider = require("./CryptoProvider");
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.SubtleCryptoProvider = void 0;
+const CryptoProvider_1 = require("./CryptoProvider");
 /**
  * `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
  *
  * This only supports asynchronous operations.
  */
-class SubtleCryptoProvider extends CryptoProvider {
+class SubtleCryptoProvider extends CryptoProvider_1.CryptoProvider {
     constructor(subtleCrypto) {
         super();
         // If no subtle crypto is interface, default to the global namespace. This
@@ -36,10 +38,10 @@ class SubtleCryptoProvider extends CryptoProvider {
         return signatureHexCodes.join('');
     }
 }
+exports.SubtleCryptoProvider = SubtleCryptoProvider;
 // Cached mapping of byte to hex representation. We do this once to avoid re-
 // computing every time we need to convert the result of a signature to hex.
 const byteHexMapping = new Array(256);
 for (let i = 0; i < byteHexMapping.length; i++) {
     byteHexMapping[i] = i.toString(16).padStart(2, '0');
 }
-module.exports = SubtleCryptoProvider;
diff --git a/lib/multipart.js b/lib/multipart.js
index 51ce8b2f..7b0a2a1f 100644
--- a/lib/multipart.js
+++ b/lib/multipart.js
@@ -1,5 +1,5 @@
 "use strict";
-const utils = require("./utils");
+const utils_1 = require("./utils");
 // Method for formatting HTTP body for the multipart/form-data specification
 // Mostly taken from Fermata.js
 // https://github.com/natevw/fermata/blob/5d9732a33d776ce925013a265935facd1626cc88/fermata.js#L315-L343
@@ -20,7 +20,7 @@ const multipartDataGenerator = (method, data, headers) => {
     function q(s) {
         return `"${s.replace(/"|"/g, '%22').replace(/\r\n|\r|\n/g, ' ')}"`;
     }
-    const flattenedData = utils.flattenAndStringify(data);
+    const flattenedData = (0, utils_1.flattenAndStringify)(data);
     for (const k in flattenedData) {
         const v = flattenedData[k];
         push(`--${segno}`);
@@ -43,7 +43,7 @@ const multipartDataGenerator = (method, data, headers) => {
 function multipartRequestDataProcessor(method, data, headers, callback) {
     data = data || {};
     if (method !== 'POST') {
-        return callback(null, utils.stringifyRequestData(data));
+        return callback(null, (0, utils_1.stringifyRequestData)(data));
     }
     this._stripe._platformFunctions
         .tryBufferData(data)
diff --git a/lib/net/FetchHttpClient.js b/lib/net/FetchHttpClient.js
index d47c2376..5c4e3871 100644
--- a/lib/net/FetchHttpClient.js
+++ b/lib/net/FetchHttpClient.js
@@ -1,6 +1,7 @@
 "use strict";
-const _HttpClient = require("./HttpClient");
-const { HttpClient, HttpClientResponse } = _HttpClient;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.FetchHttpClientResponse = exports.FetchHttpClient = void 0;
+const HttpClient_1 = require("./HttpClient");
 /**
  * HTTP client which uses a `fetch` function to issue requests.
  *
@@ -9,7 +10,7 @@ const { HttpClient, HttpClientResponse } = _HttpClient;
  * Fetch API. As an example, this could be the function provided by the
  * node-fetch package (https://github.com/node-fetch/node-fetch).
  */
-class FetchHttpClient extends HttpClient {
+class FetchHttpClient extends HttpClient_1.HttpClient {
     constructor(fetchFn) {
         super();
         this._fetchFn = fetchFn;
@@ -53,7 +54,7 @@ class FetchHttpClient extends HttpClient {
         const timeoutPromise = new Promise((_, reject) => {
             pendingTimeoutId = setTimeout(() => {
                 pendingTimeoutId = null;
-                reject(HttpClient.makeTimeoutError());
+                reject(HttpClient_1.HttpClient.makeTimeoutError());
             }, timeout);
         });
         return Promise.race([fetchPromise, timeoutPromise])
@@ -67,7 +68,8 @@ class FetchHttpClient extends HttpClient {
         });
     }
 }
-class FetchHttpClientResponse extends HttpClientResponse {
+exports.FetchHttpClient = FetchHttpClient;
+class FetchHttpClientResponse extends HttpClient_1.HttpClientResponse {
     constructor(res) {
         super(res.status, FetchHttpClientResponse._transformHeadersToObject(res.headers));
         this._res = res;
@@ -101,4 +103,4 @@ class FetchHttpClientResponse extends HttpClientResponse {
         return headersObj;
     }
 }
-module.exports = { FetchHttpClient, FetchHttpClientResponse };
+exports.FetchHttpClientResponse = FetchHttpClientResponse;
diff --git a/lib/net/HttpClient.js b/lib/net/HttpClient.js
index d49f8fb5..ab1c4726 100644
--- a/lib/net/HttpClient.js
+++ b/lib/net/HttpClient.js
@@ -1,4 +1,6 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.HttpClientResponse = exports.HttpClient = void 0;
 /**
  * Encapsulates the logic for issuing a request to the Stripe API.
  *
@@ -23,6 +25,8 @@ class HttpClient {
         return timeoutErr;
     }
 }
+exports.HttpClient = HttpClient;
+// Public API accessible via Stripe.HttpClient
 HttpClient.CONNECTION_CLOSED_ERROR_CODES = ['ECONNRESET', 'EPIPE'];
 HttpClient.TIMEOUT_ERROR_CODE = 'ETIMEDOUT';
 class HttpClientResponse {
@@ -46,4 +50,4 @@ class HttpClientResponse {
         throw new Error('toJSON not implemented.');
     }
 }
-module.exports = { HttpClient, HttpClientResponse };
+exports.HttpClientResponse = HttpClientResponse;
diff --git a/lib/net/NodeHttpClient.js b/lib/net/NodeHttpClient.js
index 02d02ab7..2b853152 100644
--- a/lib/net/NodeHttpClient.js
+++ b/lib/net/NodeHttpClient.js
@@ -1,15 +1,16 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.NodeHttpClientResponse = exports.NodeHttpClient = void 0;
 const http = require("http");
 const https = require("https");
-const _HttpClient = require("./HttpClient");
-const { HttpClient, HttpClientResponse } = _HttpClient;
+const HttpClient_1 = require("./HttpClient");
 const defaultHttpAgent = new http.Agent({ keepAlive: true });
 const defaultHttpsAgent = new https.Agent({ keepAlive: true });
 /**
  * HTTP client which uses the Node `http` and `https` packages to issue
  * requests.`
  */
-class NodeHttpClient extends HttpClient {
+class NodeHttpClient extends HttpClient_1.HttpClient {
     constructor(agent) {
         super();
         this._agent = agent;
@@ -35,7 +36,7 @@ class NodeHttpClient extends HttpClient {
                 ciphers: 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:!MD5',
             });
             req.setTimeout(timeout, () => {
-                req.destroy(HttpClient.makeTimeoutError());
+                req.destroy(HttpClient_1.HttpClient.makeTimeoutError());
             });
             req.on('response', (res) => {
                 resolve(new NodeHttpClientResponse(res));
@@ -61,7 +62,8 @@ class NodeHttpClient extends HttpClient {
         return requestPromise;
     }
 }
-class NodeHttpClientResponse extends HttpClientResponse {
+exports.NodeHttpClient = NodeHttpClient;
+class NodeHttpClientResponse extends HttpClient_1.HttpClientResponse {
     constructor(res) {
         // @ts-ignore
         super(res.statusCode, res.headers || {});
@@ -95,4 +97,4 @@ class NodeHttpClientResponse extends HttpClientResponse {
         });
     }
 }
-module.exports = { NodeHttpClient, NodeHttpClientResponse };
+exports.NodeHttpClientResponse = NodeHttpClientResponse;
diff --git a/lib/platform/NodePlatformFunctions.js b/lib/platform/NodePlatformFunctions.js
index acc6752d..104ef715 100644
--- a/lib/platform/NodePlatformFunctions.js
+++ b/lib/platform/NodePlatformFunctions.js
@@ -1,21 +1,19 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.NodePlatformFunctions = void 0;
 const crypto = require("crypto");
-const EventEmitter = require("events");
-const _Error = require("../Error");
-const StripeError = _Error.StripeError;
-const utils = require("../utils");
-const PlatformFunctions = require("./PlatformFunctions");
-const _HttpClient = require("../net/HttpClient");
-const HttpClient = _HttpClient.HttpClient;
-const _NodeHttpClient = require("../net/NodeHttpClient");
-const NodeHttpClient = _NodeHttpClient.NodeHttpClient;
-const NodeCryptoProvider = require("../crypto/NodeCryptoProvider");
-class StreamProcessingError extends StripeError {
+const events_1 = require("events");
+const NodeCryptoProvider_1 = require("../crypto/NodeCryptoProvider");
+const NodeHttpClient_1 = require("../net/NodeHttpClient");
+const PlatformFunctions_1 = require("./PlatformFunctions");
+const Error_1 = require("../Error");
+const utils_1 = require("../utils");
+class StreamProcessingError extends Error_1.StripeError {
 }
 /**
  * Specializes WebPlatformFunctions using APIs available in Node.js.
  */
-class NodePlatformFunctions extends PlatformFunctions {
+class NodePlatformFunctions extends PlatformFunctions_1.PlatformFunctions {
     constructor() {
         super();
         this._exec = require('child_process').exec;
@@ -80,11 +78,11 @@ class NodePlatformFunctions extends PlatformFunctions {
         return super.secureCompare(a, b);
     }
     createEmitter() {
-        return new EventEmitter();
+        return new events_1.EventEmitter();
     }
     /** @override */
     tryBufferData(data) {
-        if (!(data.file.data instanceof EventEmitter)) {
+        if (!(data.file.data instanceof events_1.EventEmitter)) {
             return Promise.resolve(data);
         }
         const bufferArray = [];
@@ -96,7 +94,7 @@ class NodePlatformFunctions extends PlatformFunctions {
                 .once('end', () => {
                 // @ts-ignore
                 const bufferData = Object.assign({}, data);
-                bufferData.file.data = utils.concat(bufferArray);
+                bufferData.file.data = (0, utils_1.concat)(bufferArray);
                 resolve(bufferData);
             })
                 .on('error', (err) => {
@@ -109,21 +107,19 @@ class NodePlatformFunctions extends PlatformFunctions {
     }
     /** @override */
     createNodeHttpClient(agent) {
-        // @ts-ignore
-        return new NodeHttpClient(agent);
+        return new NodeHttpClient_1.NodeHttpClient(agent);
     }
     /** @override */
     createDefaultHttpClient() {
-        // @ts-ignore
-        return new NodeHttpClient(null);
+        return new NodeHttpClient_1.NodeHttpClient();
     }
     /** @override */
     createNodeCryptoProvider() {
-        return new NodeCryptoProvider();
+        return new NodeCryptoProvider_1.NodeCryptoProvider();
     }
     /** @override */
     createDefaultCryptoProvider() {
         return this.createNodeCryptoProvider();
     }
 }
-module.exports = NodePlatformFunctions;
+exports.NodePlatformFunctions = NodePlatformFunctions;
diff --git a/lib/platform/PlatformFunctions.js b/lib/platform/PlatformFunctions.js
index 04e30d91..4b9c3de6 100644
--- a/lib/platform/PlatformFunctions.js
+++ b/lib/platform/PlatformFunctions.js
@@ -1,9 +1,8 @@
 "use strict";
-const _HttpClient = require("../net/HttpClient");
-const HttpClient = _HttpClient.HttpClient;
-const _FetchHttpClient = require("../net/FetchHttpClient");
-const FetchHttpClient = _FetchHttpClient.FetchHttpClient;
-const SubtleCryptoProvider = require("../crypto/SubtleCryptoProvider");
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.PlatformFunctions = void 0;
+const FetchHttpClient_1 = require("../net/FetchHttpClient");
+const SubtleCryptoProvider_1 = require("../crypto/SubtleCryptoProvider");
 /**
  * Interface encapsulating various utility functions whose
  * implementations depend on the platform / JS runtime.
@@ -72,8 +71,7 @@ class PlatformFunctions {
      * passed, will default to the default `fetch` function in the global scope.
      */
     createFetchHttpClient(fetchFn) {
-        // @ts-ignore
-        return new FetchHttpClient(fetchFn);
+        return new FetchHttpClient_1.FetchHttpClient(fetchFn);
     }
     /**
      * Creates an HTTP client using runtime-specific APIs.
@@ -91,10 +89,10 @@ class PlatformFunctions {
      * Creates a CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
      */
     createSubtleCryptoProvider(subtleCrypto) {
-        return new SubtleCryptoProvider(subtleCrypto);
+        return new SubtleCryptoProvider_1.SubtleCryptoProvider(subtleCrypto);
     }
     createDefaultCryptoProvider() {
         throw new Error('createDefaultCryptoProvider not implemented.');
     }
 }
-module.exports = PlatformFunctions;
+exports.PlatformFunctions = PlatformFunctions;
diff --git a/lib/platform/WebPlatformFunctions.js b/lib/platform/WebPlatformFunctions.js
index a12cf395..2386b969 100644
--- a/lib/platform/WebPlatformFunctions.js
+++ b/lib/platform/WebPlatformFunctions.js
@@ -1,19 +1,19 @@
 "use strict";
-const StripeEmitter = require("../StripeEmitter");
-const PlatformFunctions = require("./PlatformFunctions");
-const _HttpClient = require("../net/HttpClient");
-const HttpClient = _HttpClient.HttpClient;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.WebPlatformFunctions = void 0;
+const PlatformFunctions_1 = require("./PlatformFunctions");
+const StripeEmitter_1 = require("../StripeEmitter");
 /**
  * Specializes WebPlatformFunctions using APIs available in Web workers.
  */
-class WebPlatformFunctions extends PlatformFunctions {
+class WebPlatformFunctions extends PlatformFunctions_1.PlatformFunctions {
     /** @override */
     getUname() {
         return Promise.resolve(null);
     }
     /** @override */
     createEmitter() {
-        return new StripeEmitter();
+        return new StripeEmitter_1.StripeEmitter();
     }
     /** @override */
     tryBufferData(data) {
@@ -39,4 +39,4 @@ class WebPlatformFunctions extends PlatformFunctions {
         return this.createSubtleCryptoProvider();
     }
 }
-module.exports = WebPlatformFunctions;
+exports.WebPlatformFunctions = WebPlatformFunctions;
diff --git a/lib/resources.js b/lib/resources.js
index 380c3b19..1472557c 100644
--- a/lib/resources.js
+++ b/lib/resources.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const resourceNamespace = require('./ResourceNamespace');
+const { resourceNamespace } = require('./ResourceNamespace');
 module.exports = {
     // Support Accounts for consistency, Account for backwards compatibility
     Account: require('./resources/Accounts'),
diff --git a/lib/resources/AccountLinks.js b/lib/resources/AccountLinks.js
index 4e454771..a1bbe6e6 100644
--- a/lib/resources/AccountLinks.js
+++ b/lib/resources/AccountLinks.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Accounts.js b/lib/resources/Accounts.js
index 9c327d8d..303f945e 100644
--- a/lib/resources/Accounts.js
+++ b/lib/resources/Accounts.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 // Since path can either be `account` or `accounts`, support both through stripeMethod path;
 module.exports = StripeResource.extend({
diff --git a/lib/resources/ApplePayDomains.js b/lib/resources/ApplePayDomains.js
index 46fc59ad..58881afa 100644
--- a/lib/resources/ApplePayDomains.js
+++ b/lib/resources/ApplePayDomains.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/ApplicationFees.js b/lib/resources/ApplicationFees.js
index 8bf5ac12..90e1a52b 100644
--- a/lib/resources/ApplicationFees.js
+++ b/lib/resources/ApplicationFees.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Apps/Secrets.js b/lib/resources/Apps/Secrets.js
index f94086c1..30861a7b 100644
--- a/lib/resources/Apps/Secrets.js
+++ b/lib/resources/Apps/Secrets.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Balance.js b/lib/resources/Balance.js
index d1d9b4f3..0d8f0ccd 100644
--- a/lib/resources/Balance.js
+++ b/lib/resources/Balance.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/BalanceTransactions.js b/lib/resources/BalanceTransactions.js
index eb5317a7..17d10691 100644
--- a/lib/resources/BalanceTransactions.js
+++ b/lib/resources/BalanceTransactions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/BillingPortal/Configurations.js b/lib/resources/BillingPortal/Configurations.js
index a64e367e..90410624 100644
--- a/lib/resources/BillingPortal/Configurations.js
+++ b/lib/resources/BillingPortal/Configurations.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/BillingPortal/Sessions.js b/lib/resources/BillingPortal/Sessions.js
index 04ce6efa..00390979 100644
--- a/lib/resources/BillingPortal/Sessions.js
+++ b/lib/resources/BillingPortal/Sessions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Charges.js b/lib/resources/Charges.js
index f329f6b3..4ac81eb1 100644
--- a/lib/resources/Charges.js
+++ b/lib/resources/Charges.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Checkout/Sessions.js b/lib/resources/Checkout/Sessions.js
index 40adb466..2b4218e1 100644
--- a/lib/resources/Checkout/Sessions.js
+++ b/lib/resources/Checkout/Sessions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/CountrySpecs.js b/lib/resources/CountrySpecs.js
index 8aefedb5..9294ab05 100644
--- a/lib/resources/CountrySpecs.js
+++ b/lib/resources/CountrySpecs.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Coupons.js b/lib/resources/Coupons.js
index 468338f6..7ecd0498 100644
--- a/lib/resources/Coupons.js
+++ b/lib/resources/Coupons.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/CreditNotes.js b/lib/resources/CreditNotes.js
index e9b1dfb0..4a54ffe1 100644
--- a/lib/resources/CreditNotes.js
+++ b/lib/resources/CreditNotes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Customers.js b/lib/resources/Customers.js
index 76bca1e2..907b15a5 100644
--- a/lib/resources/Customers.js
+++ b/lib/resources/Customers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Disputes.js b/lib/resources/Disputes.js
index 849bd4ce..1b76c535 100644
--- a/lib/resources/Disputes.js
+++ b/lib/resources/Disputes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/EphemeralKeys.js b/lib/resources/EphemeralKeys.js
index 46722297..291d6b1e 100644
--- a/lib/resources/EphemeralKeys.js
+++ b/lib/resources/EphemeralKeys.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Events.js b/lib/resources/Events.js
index b33d17b0..1316f4a5 100644
--- a/lib/resources/Events.js
+++ b/lib/resources/Events.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/ExchangeRates.js b/lib/resources/ExchangeRates.js
index b1d58339..bcbcdff7 100644
--- a/lib/resources/ExchangeRates.js
+++ b/lib/resources/ExchangeRates.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/FileLinks.js b/lib/resources/FileLinks.js
index 3d3b0b92..a3008667 100644
--- a/lib/resources/FileLinks.js
+++ b/lib/resources/FileLinks.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Files.js b/lib/resources/Files.js
index 4b86ed3d..19bc5326 100644
--- a/lib/resources/Files.js
+++ b/lib/resources/Files.js
@@ -1,7 +1,7 @@
 // File generated from our OpenAPI spec
 'use strict';
 const { multipartRequestDataProcessor } = require('../multipart');
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/FinancialConnections/Accounts.js b/lib/resources/FinancialConnections/Accounts.js
index edd9ed42..3f8563b0 100644
--- a/lib/resources/FinancialConnections/Accounts.js
+++ b/lib/resources/FinancialConnections/Accounts.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/FinancialConnections/Sessions.js b/lib/resources/FinancialConnections/Sessions.js
index 227c3910..05236792 100644
--- a/lib/resources/FinancialConnections/Sessions.js
+++ b/lib/resources/FinancialConnections/Sessions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Identity/VerificationReports.js b/lib/resources/Identity/VerificationReports.js
index 1ceb5633..7fa2bba3 100644
--- a/lib/resources/Identity/VerificationReports.js
+++ b/lib/resources/Identity/VerificationReports.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Identity/VerificationSessions.js b/lib/resources/Identity/VerificationSessions.js
index 4984233d..d42599db 100644
--- a/lib/resources/Identity/VerificationSessions.js
+++ b/lib/resources/Identity/VerificationSessions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/InvoiceItems.js b/lib/resources/InvoiceItems.js
index cafc1429..9a6ed8de 100644
--- a/lib/resources/InvoiceItems.js
+++ b/lib/resources/InvoiceItems.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Invoices.js b/lib/resources/Invoices.js
index 16d6a96d..224a79c8 100644
--- a/lib/resources/Invoices.js
+++ b/lib/resources/Invoices.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Issuing/Authorizations.js b/lib/resources/Issuing/Authorizations.js
index 6692720c..d980fd24 100644
--- a/lib/resources/Issuing/Authorizations.js
+++ b/lib/resources/Issuing/Authorizations.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Issuing/Cardholders.js b/lib/resources/Issuing/Cardholders.js
index ea37a76d..43d84061 100644
--- a/lib/resources/Issuing/Cardholders.js
+++ b/lib/resources/Issuing/Cardholders.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Issuing/Cards.js b/lib/resources/Issuing/Cards.js
index dd63dae5..a04669ed 100644
--- a/lib/resources/Issuing/Cards.js
+++ b/lib/resources/Issuing/Cards.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Issuing/Disputes.js b/lib/resources/Issuing/Disputes.js
index 012f8157..5fb6ff88 100644
--- a/lib/resources/Issuing/Disputes.js
+++ b/lib/resources/Issuing/Disputes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Issuing/Transactions.js b/lib/resources/Issuing/Transactions.js
index c6603cbe..d1446eb0 100644
--- a/lib/resources/Issuing/Transactions.js
+++ b/lib/resources/Issuing/Transactions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Mandates.js b/lib/resources/Mandates.js
index b8d12d70..50e5ac0f 100644
--- a/lib/resources/Mandates.js
+++ b/lib/resources/Mandates.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/OAuth.js b/lib/resources/OAuth.js
index 6248fa59..5b2242f6 100644
--- a/lib/resources/OAuth.js
+++ b/lib/resources/OAuth.js
@@ -1,7 +1,7 @@
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
-const utils = require('../utils');
+const { stringifyRequestData } = require('../utils');
 const oAuthHost = 'connect.stripe.com';
 module.exports = StripeResource.extend({
     basePath: '/',
@@ -22,7 +22,7 @@ module.exports = StripeResource.extend({
         if (!params.scope) {
             params.scope = 'read_write';
         }
-        return `https://${oAuthHost}/${path}?${utils.stringifyRequestData(params)}`;
+        return `https://${oAuthHost}/${path}?${stringifyRequestData(params)}`;
     },
     token: stripeMethod({
         method: 'POST',
diff --git a/lib/resources/PaymentIntents.js b/lib/resources/PaymentIntents.js
index 4e464c0a..46276793 100644
--- a/lib/resources/PaymentIntents.js
+++ b/lib/resources/PaymentIntents.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/PaymentLinks.js b/lib/resources/PaymentLinks.js
index e693fc94..d79fcf8b 100644
--- a/lib/resources/PaymentLinks.js
+++ b/lib/resources/PaymentLinks.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/PaymentMethods.js b/lib/resources/PaymentMethods.js
index 3ce80ec6..f6193b3d 100644
--- a/lib/resources/PaymentMethods.js
+++ b/lib/resources/PaymentMethods.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Payouts.js b/lib/resources/Payouts.js
index aff8a90e..4975148c 100644
--- a/lib/resources/Payouts.js
+++ b/lib/resources/Payouts.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Plans.js b/lib/resources/Plans.js
index 0f96cb98..98b0e397 100644
--- a/lib/resources/Plans.js
+++ b/lib/resources/Plans.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Prices.js b/lib/resources/Prices.js
index f9b7cb80..2dbaf2cf 100644
--- a/lib/resources/Prices.js
+++ b/lib/resources/Prices.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Products.js b/lib/resources/Products.js
index f25ddf8d..df8f331f 100644
--- a/lib/resources/Products.js
+++ b/lib/resources/Products.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/PromotionCodes.js b/lib/resources/PromotionCodes.js
index de58217d..caccf613 100644
--- a/lib/resources/PromotionCodes.js
+++ b/lib/resources/PromotionCodes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Quotes.js b/lib/resources/Quotes.js
index 8e9a8200..4e941be4 100644
--- a/lib/resources/Quotes.js
+++ b/lib/resources/Quotes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Radar/EarlyFraudWarnings.js b/lib/resources/Radar/EarlyFraudWarnings.js
index dd609bed..44b3e136 100644
--- a/lib/resources/Radar/EarlyFraudWarnings.js
+++ b/lib/resources/Radar/EarlyFraudWarnings.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Radar/ValueListItems.js b/lib/resources/Radar/ValueListItems.js
index 864c7897..cb937920 100644
--- a/lib/resources/Radar/ValueListItems.js
+++ b/lib/resources/Radar/ValueListItems.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Radar/ValueLists.js b/lib/resources/Radar/ValueLists.js
index 90b8c66e..05a36be9 100644
--- a/lib/resources/Radar/ValueLists.js
+++ b/lib/resources/Radar/ValueLists.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Refunds.js b/lib/resources/Refunds.js
index 095193f9..89efd177 100644
--- a/lib/resources/Refunds.js
+++ b/lib/resources/Refunds.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Reporting/ReportRuns.js b/lib/resources/Reporting/ReportRuns.js
index 859e672a..2863af93 100644
--- a/lib/resources/Reporting/ReportRuns.js
+++ b/lib/resources/Reporting/ReportRuns.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Reporting/ReportTypes.js b/lib/resources/Reporting/ReportTypes.js
index 87371048..721d2dcf 100644
--- a/lib/resources/Reporting/ReportTypes.js
+++ b/lib/resources/Reporting/ReportTypes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Reviews.js b/lib/resources/Reviews.js
index 498fbac1..51af6a37 100644
--- a/lib/resources/Reviews.js
+++ b/lib/resources/Reviews.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/SetupAttempts.js b/lib/resources/SetupAttempts.js
index a7062e23..ded1913b 100644
--- a/lib/resources/SetupAttempts.js
+++ b/lib/resources/SetupAttempts.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     list: stripeMethod({
diff --git a/lib/resources/SetupIntents.js b/lib/resources/SetupIntents.js
index 57f76595..9f33a6d0 100644
--- a/lib/resources/SetupIntents.js
+++ b/lib/resources/SetupIntents.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/ShippingRates.js b/lib/resources/ShippingRates.js
index 7a7ebce8..67174480 100644
--- a/lib/resources/ShippingRates.js
+++ b/lib/resources/ShippingRates.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Sigma/ScheduledQueryRuns.js b/lib/resources/Sigma/ScheduledQueryRuns.js
index a2090790..b32e6cd1 100644
--- a/lib/resources/Sigma/ScheduledQueryRuns.js
+++ b/lib/resources/Sigma/ScheduledQueryRuns.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Sources.js b/lib/resources/Sources.js
index cdd7efb7..c95be96c 100644
--- a/lib/resources/Sources.js
+++ b/lib/resources/Sources.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/SubscriptionItems.js b/lib/resources/SubscriptionItems.js
index 52345650..96a274b3 100644
--- a/lib/resources/SubscriptionItems.js
+++ b/lib/resources/SubscriptionItems.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/SubscriptionSchedules.js b/lib/resources/SubscriptionSchedules.js
index 5027db26..0d33f800 100644
--- a/lib/resources/SubscriptionSchedules.js
+++ b/lib/resources/SubscriptionSchedules.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Subscriptions.js b/lib/resources/Subscriptions.js
index bf2572ed..46fb27c4 100644
--- a/lib/resources/Subscriptions.js
+++ b/lib/resources/Subscriptions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/TaxCodes.js b/lib/resources/TaxCodes.js
index 84b9e9c4..73dd474e 100644
--- a/lib/resources/TaxCodes.js
+++ b/lib/resources/TaxCodes.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/TaxRates.js b/lib/resources/TaxRates.js
index 6222ec54..3b0aad95 100644
--- a/lib/resources/TaxRates.js
+++ b/lib/resources/TaxRates.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Terminal/Configurations.js b/lib/resources/Terminal/Configurations.js
index 5b2b48bf..0fbb272a 100644
--- a/lib/resources/Terminal/Configurations.js
+++ b/lib/resources/Terminal/Configurations.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Terminal/ConnectionTokens.js b/lib/resources/Terminal/ConnectionTokens.js
index 03b0ddef..6cc5600b 100644
--- a/lib/resources/Terminal/ConnectionTokens.js
+++ b/lib/resources/Terminal/ConnectionTokens.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Terminal/Locations.js b/lib/resources/Terminal/Locations.js
index 9179d077..4935ba22 100644
--- a/lib/resources/Terminal/Locations.js
+++ b/lib/resources/Terminal/Locations.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Terminal/Readers.js b/lib/resources/Terminal/Readers.js
index bb96e2d6..b30c5326 100644
--- a/lib/resources/Terminal/Readers.js
+++ b/lib/resources/Terminal/Readers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Tokens.js b/lib/resources/Tokens.js
index a2e355d5..71ef976e 100644
--- a/lib/resources/Tokens.js
+++ b/lib/resources/Tokens.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Topups.js b/lib/resources/Topups.js
index 7bcf6571..6d337b3b 100644
--- a/lib/resources/Topups.js
+++ b/lib/resources/Topups.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Transfers.js b/lib/resources/Transfers.js
index 544d3d31..0426fcf9 100644
--- a/lib/resources/Transfers.js
+++ b/lib/resources/Transfers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/CreditReversals.js b/lib/resources/Treasury/CreditReversals.js
index 95d6e211..20e3e866 100644
--- a/lib/resources/Treasury/CreditReversals.js
+++ b/lib/resources/Treasury/CreditReversals.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/DebitReversals.js b/lib/resources/Treasury/DebitReversals.js
index 0f53944f..9789749e 100644
--- a/lib/resources/Treasury/DebitReversals.js
+++ b/lib/resources/Treasury/DebitReversals.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/FinancialAccounts.js b/lib/resources/Treasury/FinancialAccounts.js
index 5f3d0dd8..37393113 100644
--- a/lib/resources/Treasury/FinancialAccounts.js
+++ b/lib/resources/Treasury/FinancialAccounts.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/InboundTransfers.js b/lib/resources/Treasury/InboundTransfers.js
index 52caf10f..67ce0148 100644
--- a/lib/resources/Treasury/InboundTransfers.js
+++ b/lib/resources/Treasury/InboundTransfers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/OutboundPayments.js b/lib/resources/Treasury/OutboundPayments.js
index d6d0225c..dd5fa7d3 100644
--- a/lib/resources/Treasury/OutboundPayments.js
+++ b/lib/resources/Treasury/OutboundPayments.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/OutboundTransfers.js b/lib/resources/Treasury/OutboundTransfers.js
index fc9ca46a..14995218 100644
--- a/lib/resources/Treasury/OutboundTransfers.js
+++ b/lib/resources/Treasury/OutboundTransfers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/Treasury/ReceivedCredits.js b/lib/resources/Treasury/ReceivedCredits.js
index 533398ce..431d4ddc 100644
--- a/lib/resources/Treasury/ReceivedCredits.js
+++ b/lib/resources/Treasury/ReceivedCredits.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Treasury/ReceivedDebits.js b/lib/resources/Treasury/ReceivedDebits.js
index f4de1b78..3da821f3 100644
--- a/lib/resources/Treasury/ReceivedDebits.js
+++ b/lib/resources/Treasury/ReceivedDebits.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Treasury/TransactionEntries.js b/lib/resources/Treasury/TransactionEntries.js
index f899ea91..ab4ac8a8 100644
--- a/lib/resources/Treasury/TransactionEntries.js
+++ b/lib/resources/Treasury/TransactionEntries.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/Treasury/Transactions.js b/lib/resources/Treasury/Transactions.js
index d8c0b0ae..55b0d415 100644
--- a/lib/resources/Treasury/Transactions.js
+++ b/lib/resources/Treasury/Transactions.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     retrieve: stripeMethod({
diff --git a/lib/resources/WebhookEndpoints.js b/lib/resources/WebhookEndpoints.js
index 72c257d6..9d110266 100644
--- a/lib/resources/WebhookEndpoints.js
+++ b/lib/resources/WebhookEndpoints.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../StripeResource');
+const { StripeResource } = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/stripe.common.js b/lib/stripe.common.js
index 229c0aaa..94ad4d03 100644
--- a/lib/stripe.common.js
+++ b/lib/stripe.common.js
@@ -1,13 +1,19 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createStripe = void 0;
 const _Error = require("./Error");
-const resources = require("./resources");
+const HttpClient_1 = require("./net/HttpClient");
+const utils_1 = require("./utils");
+const CryptoProvider_1 = require("./crypto/CryptoProvider");
+const RequestSender_1 = require("./RequestSender");
+const StripeResource_1 = require("./StripeResource");
+const Webhooks_1 = require("./Webhooks");
+const resources = require('./resources');
 const DEFAULT_HOST = 'api.stripe.com';
 const DEFAULT_PORT = '443';
 const DEFAULT_BASE_PATH = '/v1/';
 const DEFAULT_API_VERSION = null;
 const DEFAULT_TIMEOUT = 80000;
-const utils = require("./utils");
-const { determineProcessUserAgentProperties } = utils;
 const MAX_NETWORK_RETRY_DELAY_SEC = 2;
 const INITIAL_NETWORK_RETRY_DELAY_SEC = 0.5;
 const APP_INFO_PROPERTIES = ['name', 'version', 'url', 'partner_id'];
@@ -25,20 +31,15 @@ const ALLOWED_CONFIG_PROPERTIES = [
     'appInfo',
     'stripeAccount',
 ];
-const StripeResource = require("./StripeResource");
-const RequestSender = require("./RequestSender");
-const HttpClient = require("./net/HttpClient");
-const CryptoProvider = require("./crypto/CryptoProvider");
-const createWebhooks = require("./Webhooks");
-const defaultRequestSenderFactory = (stripe) => new RequestSender(stripe, StripeResource.MAX_BUFFERED_REQUEST_METRICS);
+const defaultRequestSenderFactory = (stripe) => new RequestSender_1.RequestSender(stripe, StripeResource_1.StripeResource.MAX_BUFFERED_REQUEST_METRICS);
 function createStripe(platformFunctions, requestSender = defaultRequestSenderFactory) {
     Stripe.PACKAGE_VERSION = require('../package.json').version;
-    Stripe.USER_AGENT = Object.assign({ bindings_version: Stripe.PACKAGE_VERSION, lang: 'node', publisher: 'stripe', uname: null, typescript: false }, determineProcessUserAgentProperties());
-    Stripe.StripeResource = StripeResource;
+    Stripe.USER_AGENT = Object.assign({ bindings_version: Stripe.PACKAGE_VERSION, lang: 'node', publisher: 'stripe', uname: null, typescript: false }, (0, utils_1.determineProcessUserAgentProperties)());
+    Stripe.StripeResource = StripeResource_1.StripeResource;
     Stripe.resources = resources;
-    Stripe.HttpClient = HttpClient.HttpClient;
-    Stripe.HttpClientResponse = HttpClient.HttpClientResponse;
-    Stripe.CryptoProvider = CryptoProvider;
+    Stripe.HttpClient = HttpClient_1.HttpClient;
+    Stripe.HttpClientResponse = HttpClient_1.HttpClientResponse;
+    Stripe.CryptoProvider = CryptoProvider_1.CryptoProvider;
     function Stripe(key, config = {}) {
         if (!(this instanceof Stripe)) {
             return new Stripe(key, config);
@@ -68,8 +69,8 @@ function createStripe(platformFunctions, requestSender = defaultRequestSenderFac
             protocol: props.protocol || 'https',
             basePath: DEFAULT_BASE_PATH,
             version: props.apiVersion || DEFAULT_API_VERSION,
-            timeout: utils.validateInteger('timeout', props.timeout, DEFAULT_TIMEOUT),
-            maxNetworkRetries: utils.validateInteger('maxNetworkRetries', props.maxNetworkRetries, 0),
+            timeout: (0, utils_1.validateInteger)('timeout', props.timeout, DEFAULT_TIMEOUT),
+            maxNetworkRetries: (0, utils_1.validateInteger)('maxNetworkRetries', props.maxNetworkRetries, 0),
             agent: agent,
             httpClient: props.httpClient ||
                 (agent
@@ -92,7 +93,7 @@ function createStripe(platformFunctions, requestSender = defaultRequestSenderFac
         this._prepResources();
         this._setApiKey(key);
         this.errors = _Error;
-        this.webhooks = createWebhooks(platformFunctions);
+        this.webhooks = (0, Webhooks_1.createWebhooks)(platformFunctions);
         this._prevRequestMetrics = [];
         this._enableTelemetry = props.telemetry !== false;
         this._requestSender = requestSender(this);
@@ -101,7 +102,7 @@ function createStripe(platformFunctions, requestSender = defaultRequestSenderFac
         this.StripeResource = Stripe.StripeResource;
     }
     Stripe.errors = _Error;
-    Stripe.webhooks = require('./Webhooks');
+    Stripe.webhooks = Webhooks_1.createWebhooks;
     Stripe.createNodeHttpClient = platformFunctions.createNodeHttpClient;
     /**
      * Creates an HTTP client for issuing Stripe API requests which uses the Web
@@ -229,7 +230,7 @@ function createStripe(platformFunctions, requestSender = defaultRequestSenderFac
          * This may be removed in the future.
          */
         _setApiNumberField(prop, n, defaultVal) {
-            const val = utils.validateInteger(prop, n, defaultVal);
+            const val = (0, utils_1.validateInteger)(prop, n, defaultVal);
             this._setApiField(prop, val);
         },
         getMaxNetworkRetryDelay() {
@@ -310,7 +311,7 @@ function createStripe(platformFunctions, requestSender = defaultRequestSenderFac
         _prepResources() {
             for (const name in resources) {
                 // @ts-ignore
-                this[utils.pascalToCamelCase(name)] = new resources[name](this);
+                this[(0, utils_1.pascalToCamelCase)(name)] = new resources[name](this);
             }
         },
         /**
@@ -344,4 +345,4 @@ function createStripe(platformFunctions, requestSender = defaultRequestSenderFac
     };
     return Stripe;
 }
-module.exports = { createStripe };
+exports.createStripe = createStripe;
diff --git a/lib/stripe.node.js b/lib/stripe.node.js
index 097f7fd8..9eaf0fd2 100644
--- a/lib/stripe.node.js
+++ b/lib/stripe.node.js
@@ -1,8 +1,8 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-const _Stripe = require("./stripe.common");
-const NodePlatformFunctions = require("./platform/NodePlatformFunctions");
-const Stripe = _Stripe.createStripe(new NodePlatformFunctions());
+const NodePlatformFunctions_1 = require("./platform/NodePlatformFunctions");
+const stripe_common_1 = require("./stripe.common");
+const Stripe = (0, stripe_common_1.createStripe)(new NodePlatformFunctions_1.NodePlatformFunctions());
 module.exports = Stripe;
 // expose constructor as a named property to enable mocking with Sinon.JS
 module.exports.Stripe = Stripe;
diff --git a/lib/stripe.worker.js b/lib/stripe.worker.js
index a67c79d1..71c53787 100644
--- a/lib/stripe.worker.js
+++ b/lib/stripe.worker.js
@@ -1,8 +1,8 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-const _Stripe = require("./stripe.common");
-const WebPlatformFunctions = require("./platform/WebPlatformFunctions");
-const Stripe = _Stripe.createStripe(new WebPlatformFunctions());
+const WebPlatformFunctions_1 = require("./platform/WebPlatformFunctions");
+const stripe_common_1 = require("./stripe.common");
+const Stripe = (0, stripe_common_1.createStripe)(new WebPlatformFunctions_1.WebPlatformFunctions());
 module.exports = Stripe;
 // expose constructor as a named property to enable mocking with Sinon.JS
 module.exports.Stripe = Stripe;
diff --git a/lib/utils.js b/lib/utils.js
index 3c4f23f7..7622b011 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -1,4 +1,6 @@
 "use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.concat = exports.determineProcessUserAgentProperties = exports.validateInteger = exports.flattenAndStringify = exports.isObject = exports.emitWarning = exports.pascalToCamelCase = exports.callbackifyPromiseWithTimeout = exports.normalizeHeader = exports.normalizeHeaders = exports.removeNullish = exports.protoExtend = exports.getOptionsFromArgs = exports.getDataFromArgs = exports.extractUrlParams = exports.makeURLInterpolator = exports.stringifyRequestData = exports.isOptionsHash = void 0;
 const qs = require('qs');
 const OPTIONS_KEYS = [
     'apiKey',
@@ -9,283 +11,298 @@ const OPTIONS_KEYS = [
     'timeout',
     'host',
 ];
-const utils = {
-    isOptionsHash(o) {
-        return (o &&
-            typeof o === 'object' &&
-            OPTIONS_KEYS.some((prop) => Object.prototype.hasOwnProperty.call(o, prop)));
-    },
-    /**
-     * Stringifies an Object, accommodating nested objects
-     * (forming the conventional key 'parent[child]=value')
-     */
-    stringifyRequestData: (data) => {
-        return (qs
-            .stringify(data, {
-            serializeDate: (d) => Math.floor(d.getTime() / 1000),
-        })
-            // 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, ']'));
-    },
-    /**
-     * Outputs a new function with interpolated object property values.
-     * Use like so:
-     *   const fn = makeURLInterpolator('some/url/{param1}/{param2}');
-     *   fn({ param1: 123, param2: 456 }); // => 'some/url/123/456'
-     */
-    makeURLInterpolator: (() => {
-        const rc = {
-            '\n': '\\n',
-            '"': '\\"',
-            '\u2028': '\\u2028',
-            '\u2029': '\\u2029',
-        };
-        return (str) => {
-            const cleanString = str.replace(/["\n\r\u2028\u2029]/g, ($0) => rc[$0]);
-            return (outputs) => {
-                return cleanString.replace(/\{([\s\S]+?)\}/g, ($0, $1) => 
-                // @ts-ignore
-                encodeURIComponent(outputs[$1] || ''));
-            };
+// const utils = {
+function isOptionsHash(o) {
+    return (o &&
+        typeof o === 'object' &&
+        OPTIONS_KEYS.some((prop) => Object.prototype.hasOwnProperty.call(o, prop)));
+}
+exports.isOptionsHash = isOptionsHash;
+/**
+ * Stringifies an Object, accommodating nested objects
+ * (forming the conventional key 'parent[child]=value')
+ */
+function stringifyRequestData(data) {
+    return (qs
+        .stringify(data, {
+        serializeDate: (d) => Math.floor(d.getTime() / 1000),
+    })
+        // 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, ']'));
+}
+exports.stringifyRequestData = stringifyRequestData;
+/**
+ * Outputs a new function with interpolated object property values.
+ * Use like so:
+ *   const fn = makeURLInterpolator('some/url/{param1}/{param2}');
+ *   fn({ param1: 123, param2: 456 }); // => 'some/url/123/456'
+ */
+exports.makeURLInterpolator = (() => {
+    const rc = {
+        '\n': '\\n',
+        '"': '\\"',
+        '\u2028': '\\u2028',
+        '\u2029': '\\u2029',
+    };
+    return (str) => {
+        const cleanString = str.replace(/["\n\r\u2028\u2029]/g, ($0) => rc[$0]);
+        return (outputs) => {
+            return cleanString.replace(/\{([\s\S]+?)\}/g, ($0, $1) => 
+            // @ts-ignore
+            encodeURIComponent(outputs[$1] || ''));
         };
-    })(),
-    extractUrlParams: (path) => {
-        const params = path.match(/\{\w+\}/g);
-        if (!params) {
-            return [];
-        }
-        return params.map((param) => param.replace(/[{}]/g, ''));
-    },
-    /**
-     * Return the data argument from a list of arguments
-     *
-     * @param {object[]} args
-     * @returns {object}
-     */
-    getDataFromArgs(args) {
-        if (!Array.isArray(args) || !args[0] || typeof args[0] !== 'object') {
-            return {};
-        }
-        if (!utils.isOptionsHash(args[0])) {
-            return args.shift();
-        }
-        const argKeys = Object.keys(args[0]);
-        const optionKeysInArgs = argKeys.filter((key) => OPTIONS_KEYS.includes(key));
-        // In some cases options may be the provided as the first argument.
-        // Here we're detecting a case where there are two distinct arguments
-        // (the first being args and the second options) and with known
-        // option keys in the first so that we can warn the user about it.
-        if (optionKeysInArgs.length > 0 &&
-            optionKeysInArgs.length !== argKeys.length) {
-            emitWarning(`Options found in arguments (${optionKeysInArgs.join(', ')}). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.`);
-        }
+    };
+})();
+function extractUrlParams(path) {
+    const params = path.match(/\{\w+\}/g);
+    if (!params) {
+        return [];
+    }
+    return params.map((param) => param.replace(/[{}]/g, ''));
+}
+exports.extractUrlParams = extractUrlParams;
+/**
+ * Return the data argument from a list of arguments
+ *
+ * @param {object[]} args
+ * @returns {object}
+ */
+function getDataFromArgs(args) {
+    if (!Array.isArray(args) || !args[0] || typeof args[0] !== 'object') {
         return {};
-    },
-    /**
-     * Return the options hash from a list of arguments
-     */
-    getOptionsFromArgs: (args) => {
-        const opts = {
-            auth: null,
-            host: null,
-            headers: {},
-            settings: {},
-        };
-        if (args.length > 0) {
-            const arg = args[args.length - 1];
-            if (typeof arg === 'string') {
-                opts.auth = args.pop();
+    }
+    if (!isOptionsHash(args[0])) {
+        return args.shift();
+    }
+    const argKeys = Object.keys(args[0]);
+    const optionKeysInArgs = argKeys.filter((key) => OPTIONS_KEYS.includes(key));
+    // In some cases options may be the provided as the first argument.
+    // Here we're detecting a case where there are two distinct arguments
+    // (the first being args and the second options) and with known
+    // option keys in the first so that we can warn the user about it.
+    if (optionKeysInArgs.length > 0 &&
+        optionKeysInArgs.length !== argKeys.length) {
+        emitWarning(`Options found in arguments (${optionKeysInArgs.join(', ')}). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.`);
+    }
+    return {};
+}
+exports.getDataFromArgs = getDataFromArgs;
+/**
+ * Return the options hash from a list of arguments
+ */
+function getOptionsFromArgs(args) {
+    const opts = {
+        auth: null,
+        host: null,
+        headers: {},
+        settings: {},
+    };
+    if (args.length > 0) {
+        const arg = args[args.length - 1];
+        if (typeof arg === 'string') {
+            opts.auth = args.pop();
+        }
+        else if (isOptionsHash(arg)) {
+            const params = Object.assign({}, args.pop());
+            const extraKeys = Object.keys(params).filter((key) => !OPTIONS_KEYS.includes(key));
+            if (extraKeys.length) {
+                emitWarning(`Invalid options found (${extraKeys.join(', ')}); ignoring.`);
             }
-            else if (utils.isOptionsHash(arg)) {
-                const params = Object.assign({}, args.pop());
-                const extraKeys = Object.keys(params).filter((key) => !OPTIONS_KEYS.includes(key));
-                if (extraKeys.length) {
-                    emitWarning(`Invalid options found (${extraKeys.join(', ')}); ignoring.`);
-                }
-                if (params.apiKey) {
-                    opts.auth = params.apiKey;
-                }
-                if (params.idempotencyKey) {
-                    opts.headers['Idempotency-Key'] = params.idempotencyKey;
-                }
-                if (params.stripeAccount) {
-                    opts.headers['Stripe-Account'] = params.stripeAccount;
-                }
-                if (params.apiVersion) {
-                    opts.headers['Stripe-Version'] = params.apiVersion;
-                }
-                if (Number.isInteger(params.maxNetworkRetries)) {
-                    opts.settings.maxNetworkRetries = params.maxNetworkRetries;
-                }
-                if (Number.isInteger(params.timeout)) {
-                    opts.settings.timeout = params.timeout;
-                }
-                if (params.host) {
-                    opts.host = params.host;
-                }
+            if (params.apiKey) {
+                opts.auth = params.apiKey;
             }
-        }
-        return opts;
-    },
-    /**
-     * Provide simple "Class" extension mechanism
-     */
-    protoExtend(sub) {
-        // eslint-disable-next-line @typescript-eslint/no-this-alias
-        const Super = this;
-        const Constructor = Object.prototype.hasOwnProperty.call(sub, 'constructor')
-            ? sub.constructor
-            : function (...args) {
-                Super.apply(this, args);
-            };
-        // This initialization logic is somewhat sensitive to be compatible with
-        // divergent JS implementations like the one found in Qt. See here for more
-        // context:
-        //
-        // https://github.com/stripe/stripe-node/pull/334
-        Object.assign(Constructor, Super);
-        Constructor.prototype = Object.create(Super.prototype);
-        Object.assign(Constructor.prototype, sub);
-        return Constructor;
-    },
-    /**
-     * Remove empty values from an object
-     */
-    removeNullish: (obj) => {
-        if (typeof obj !== 'object') {
-            throw new Error('Argument must be an object');
-        }
-        return Object.keys(obj).reduce((result, key) => {
-            if (obj[key] != null) {
-                result[key] = obj[key];
+            if (params.idempotencyKey) {
+                opts.headers['Idempotency-Key'] = params.idempotencyKey;
+            }
+            if (params.stripeAccount) {
+                opts.headers['Stripe-Account'] = params.stripeAccount;
+            }
+            if (params.apiVersion) {
+                opts.headers['Stripe-Version'] = params.apiVersion;
+            }
+            if (Number.isInteger(params.maxNetworkRetries)) {
+                opts.settings.maxNetworkRetries = params.maxNetworkRetries;
+            }
+            if (Number.isInteger(params.timeout)) {
+                opts.settings.timeout = params.timeout;
+            }
+            if (params.host) {
+                opts.host = params.host;
             }
-            return result;
-        }, {});
-    },
-    /**
-     * Normalize standard HTTP Headers:
-     * {'foo-bar': 'hi'}
-     * becomes
-     * {'Foo-Bar': 'hi'}
-     */
-    normalizeHeaders: (obj) => {
-        if (!(obj && typeof obj === 'object')) {
-            return obj;
-        }
-        return Object.keys(obj).reduce((result, header) => {
-            result[utils.normalizeHeader(header)] = obj[header];
-            return result;
-        }, {});
-    },
-    /**
-     * Stolen from https://github.com/marten-de-vries/header-case-normalizer/blob/master/index.js#L36-L41
-     * without the exceptions which are irrelevant to us.
-     */
-    normalizeHeader: (header) => {
-        return header
-            .split('-')
-            .map((text) => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase())
-            .join('-');
-    },
-    callbackifyPromiseWithTimeout: (promise, callback) => {
-        if (callback) {
-            // Ensure callback is called outside of promise stack.
-            return promise.then((res) => {
-                setTimeout(() => {
-                    callback(null, res);
-                }, 0);
-            }, (err) => {
-                setTimeout(() => {
-                    callback(err, null);
-                }, 0);
-            });
-        }
-        return promise;
-    },
-    /**
-     * Allow for special capitalization cases (such as OAuth)
-     */
-    pascalToCamelCase: (name) => {
-        if (name === 'OAuth') {
-            return 'oauth';
         }
-        else {
-            return name[0].toLowerCase() + name.substring(1);
+    }
+    return opts;
+}
+exports.getOptionsFromArgs = getOptionsFromArgs;
+/**
+ * Provide simple "Class" extension mechanism.
+ * <!-- Public API accessible via Stripe.StripeResource.extend -->
+ */
+function protoExtend(sub) {
+    // eslint-disable-next-line @typescript-eslint/no-this-alias
+    const Super = this;
+    const Constructor = Object.prototype.hasOwnProperty.call(sub, 'constructor')
+        ? sub.constructor
+        : function (...args) {
+            Super.apply(this, args);
+        };
+    // This initialization logic is somewhat sensitive to be compatible with
+    // divergent JS implementations like the one found in Qt. See here for more
+    // context:
+    //
+    // https://github.com/stripe/stripe-node/pull/334
+    Object.assign(Constructor, Super);
+    Constructor.prototype = Object.create(Super.prototype);
+    Object.assign(Constructor.prototype, sub);
+    return Constructor;
+}
+exports.protoExtend = protoExtend;
+/**
+ * Remove empty values from an object
+ */
+function removeNullish(obj) {
+    if (typeof obj !== 'object') {
+        throw new Error('Argument must be an object');
+    }
+    return Object.keys(obj).reduce((result, key) => {
+        if (obj[key] != null) {
+            result[key] = obj[key];
         }
-    },
-    emitWarning,
-    isObject: (obj) => {
-        const type = typeof obj;
-        return (type === 'function' || type === 'object') && !!obj;
-    },
-    // For use in multipart requests
-    flattenAndStringify: (data) => {
-        const result = {};
-        const step = (obj, prevKey) => {
-            Object.keys(obj).forEach((key) => {
-                // @ts-ignore
-                const value = obj[key];
-                const newKey = prevKey ? `${prevKey}[${key}]` : key;
-                if (utils.isObject(value)) {
-                    if (!(value instanceof Uint8Array) &&
-                        !Object.prototype.hasOwnProperty.call(value, 'data')) {
-                        // Non-buffer non-file Objects are recursively flattened
-                        return step(value, newKey);
-                    }
-                    else {
-                        // Buffers and file objects are stored without modification
-                        result[newKey] = value;
-                    }
+        return result;
+    }, {});
+}
+exports.removeNullish = removeNullish;
+/**
+ * Normalize standard HTTP Headers:
+ * {'foo-bar': 'hi'}
+ * becomes
+ * {'Foo-Bar': 'hi'}
+ */
+function normalizeHeaders(obj) {
+    if (!(obj && typeof obj === 'object')) {
+        return obj;
+    }
+    return Object.keys(obj).reduce((result, header) => {
+        result[normalizeHeader(header)] = obj[header];
+        return result;
+    }, {});
+}
+exports.normalizeHeaders = normalizeHeaders;
+/**
+ * Stolen from https://github.com/marten-de-vries/header-case-normalizer/blob/master/index.js#L36-L41
+ * without the exceptions which are irrelevant to us.
+ */
+function normalizeHeader(header) {
+    return header
+        .split('-')
+        .map((text) => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase())
+        .join('-');
+}
+exports.normalizeHeader = normalizeHeader;
+function callbackifyPromiseWithTimeout(promise, callback) {
+    if (callback) {
+        // Ensure callback is called outside of promise stack.
+        return promise.then((res) => {
+            setTimeout(() => {
+                callback(null, res);
+            }, 0);
+        }, (err) => {
+            setTimeout(() => {
+                callback(err, null);
+            }, 0);
+        });
+    }
+    return promise;
+}
+exports.callbackifyPromiseWithTimeout = callbackifyPromiseWithTimeout;
+/**
+ * Allow for special capitalization cases (such as OAuth)
+ */
+function pascalToCamelCase(name) {
+    if (name === 'OAuth') {
+        return 'oauth';
+    }
+    else {
+        return name[0].toLowerCase() + name.substring(1);
+    }
+}
+exports.pascalToCamelCase = pascalToCamelCase;
+function emitWarning(warning) {
+    if (typeof process.emitWarning !== 'function') {
+        return console.warn(`Stripe: ${warning}`); /* eslint-disable-line no-console */
+    }
+    return process.emitWarning(warning, 'Stripe');
+}
+exports.emitWarning = emitWarning;
+function isObject(obj) {
+    const type = typeof obj;
+    return (type === 'function' || type === 'object') && !!obj;
+}
+exports.isObject = isObject;
+// For use in multipart requests
+function flattenAndStringify(data) {
+    const result = {};
+    const step = (obj, prevKey) => {
+        Object.keys(obj).forEach((key) => {
+            // @ts-ignore
+            const value = obj[key];
+            const newKey = prevKey ? `${prevKey}[${key}]` : key;
+            if (isObject(value)) {
+                if (!(value instanceof Uint8Array) &&
+                    !Object.prototype.hasOwnProperty.call(value, 'data')) {
+                    // Non-buffer non-file Objects are recursively flattened
+                    return step(value, newKey);
                 }
                 else {
-                    // Primitives are converted to strings
-                    result[newKey] = String(value);
+                    // Buffers and file objects are stored without modification
+                    result[newKey] = value;
                 }
-            });
-        };
-        step(data, null);
-        return result;
-    },
-    validateInteger: (name, n, defaultVal) => {
-        if (!Number.isInteger(n)) {
-            if (defaultVal !== undefined) {
-                return defaultVal;
             }
             else {
-                throw new Error(`${name} must be an integer`);
+                // Primitives are converted to strings
+                result[newKey] = String(value);
             }
-        }
-        return n;
-    },
-    determineProcessUserAgentProperties: () => {
-        return typeof process === 'undefined'
-            ? {}
-            : {
-                lang_version: process.version,
-                platform: process.platform,
-            };
-    },
-    /**
-     * Joins an array of Uint8Arrays into a single Uint8Array
-     */
-    concat: (arrays) => {
-        const totalLength = arrays.reduce((len, array) => len + array.length, 0);
-        const merged = new Uint8Array(totalLength);
-        let offset = 0;
-        arrays.forEach((array) => {
-            merged.set(array, offset);
-            offset += array.length;
         });
-        return merged;
-    },
-};
-function emitWarning(warning) {
-    if (typeof process.emitWarning !== 'function') {
-        return console.warn(`Stripe: ${warning}`); /* eslint-disable-line no-console */
+    };
+    step(data, null);
+    return result;
+}
+exports.flattenAndStringify = flattenAndStringify;
+function validateInteger(name, n, defaultVal) {
+    if (!Number.isInteger(n)) {
+        if (defaultVal !== undefined) {
+            return defaultVal;
+        }
+        else {
+            throw new Error(`${name} must be an integer`);
+        }
     }
-    return process.emitWarning(warning, 'Stripe');
+    return n;
+}
+exports.validateInteger = validateInteger;
+function determineProcessUserAgentProperties() {
+    return typeof process === 'undefined'
+        ? {}
+        : {
+            lang_version: process.version,
+            platform: process.platform,
+        };
+}
+exports.determineProcessUserAgentProperties = determineProcessUserAgentProperties;
+/**
+ * Joins an array of Uint8Arrays into a single Uint8Array
+ */
+function concat(arrays) {
+    const totalLength = arrays.reduce((len, array) => len + array.length, 0);
+    const merged = new Uint8Array(totalLength);
+    let offset = 0;
+    arrays.forEach((array) => {
+        merged.set(array, offset);
+        offset += array.length;
+    });
+    return merged;
 }
-module.exports = utils;
+exports.concat = concat;
diff --git a/package.json b/package.json
index 367ff4fc..f34e07f0 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
     "@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",
diff --git a/src/Error.ts b/src/Error.ts
index c1d13eb4..a1cb8527 100644
--- a/src/Error.ts
+++ b/src/Error.ts
@@ -1,9 +1,31 @@
 /* eslint-disable camelcase */
+
+export const generate = (rawStripeError: StripeRawError): StripeError => {
+  switch (rawStripeError.type) {
+    case 'card_error':
+      return new StripeCardError(rawStripeError);
+    case 'invalid_request_error':
+      return new StripeInvalidRequestError(rawStripeError);
+    case 'api_error':
+      return new StripeAPIError(rawStripeError);
+    case 'authentication_error':
+      return new StripeAuthenticationError(rawStripeError);
+    case 'rate_limit_error':
+      return new StripeRateLimitError(rawStripeError);
+    case 'idempotency_error':
+      return new StripeIdempotencyError(rawStripeError);
+    case 'invalid_grant':
+      return new StripeInvalidGrantError(rawStripeError);
+    default:
+      return new StripeUnknownError(rawStripeError);
+  }
+};
+
 /**
  * StripeError is the base error from which all other more specific Stripe errors derive.
  * Specifically for errors returned from Stripe's REST API.
  */
-class StripeError extends Error {
+export class StripeError extends Error {
   readonly message: string;
   readonly type: string;
   readonly raw: unknown;
@@ -53,26 +75,7 @@ class StripeError extends Error {
   /**
    * Helper factory which takes raw stripe errors and outputs wrapping instances
    */
-  static generate(rawStripeError: StripeRawError): StripeError {
-    switch (rawStripeError.type) {
-      case 'card_error':
-        return new StripeCardError(rawStripeError);
-      case 'invalid_request_error':
-        return new StripeInvalidRequestError(rawStripeError);
-      case 'api_error':
-        return new StripeAPIError(rawStripeError);
-      case 'authentication_error':
-        return new StripeAuthenticationError(rawStripeError);
-      case 'rate_limit_error':
-        return new StripeRateLimitError(rawStripeError);
-      case 'idempotency_error':
-        return new StripeIdempotencyError(rawStripeError);
-      case 'invalid_grant':
-        return new StripeInvalidGrantError(rawStripeError);
-      default:
-        return new StripeUnknownError(rawStripeError);
-    }
-  }
+  static generate = generate;
 }
 
 // Specific Stripe Error types:
@@ -81,13 +84,13 @@ class StripeError extends Error {
  * CardError is raised when a user enters a card that can't be charged for
  * some reason.
  */
-class StripeCardError extends StripeError {}
+export class StripeCardError extends StripeError {}
 
 /**
  * InvalidRequestError is raised when a request is initiated with invalid
  * parameters.
  */
-class StripeInvalidRequestError extends StripeError {}
+export class StripeInvalidRequestError extends StripeError {}
 
 /**
  * APIError is a generic error that may be raised in cases where none of the
@@ -95,39 +98,39 @@ class StripeInvalidRequestError extends StripeError {}
  * that a new error has been introduced in the API, but this version of the
  * Node.JS SDK doesn't know how to handle it.
  */
-class StripeAPIError extends StripeError {}
+export class StripeAPIError extends StripeError {}
 
 /**
  * AuthenticationError is raised when invalid credentials are used to connect
  * to Stripe's servers.
  */
-class StripeAuthenticationError extends StripeError {}
+export class StripeAuthenticationError extends StripeError {}
 
 /**
  * PermissionError is raised in cases where access was attempted on a resource
  * that wasn't allowed.
  */
-class StripePermissionError extends StripeError {}
+export class StripePermissionError extends StripeError {}
 
 /**
  * RateLimitError is raised in cases where an account is putting too much load
  * on Stripe's API servers (usually by performing too many requests). Please
  * back off on request rate.
  */
-class StripeRateLimitError extends StripeError {}
+export class StripeRateLimitError extends StripeError {}
 
 /**
  * StripeConnectionError is raised in the event that the SDK can't connect to
  * Stripe's servers. That can be for a variety of different reasons from a
  * downed network to a bad TLS certificate.
  */
-class StripeConnectionError extends StripeError {}
+export class StripeConnectionError extends StripeError {}
 
 /**
  * SignatureVerificationError is raised when the signature verification for a
  * webhook fails
  */
-class StripeSignatureVerificationError extends StripeError {
+export class StripeSignatureVerificationError extends StripeError {
   header: string | Uint8Array;
   payload: string | Uint8Array;
 
@@ -146,7 +149,7 @@ class StripeSignatureVerificationError extends StripeError {
  * IdempotencyError is raised in cases where an idempotency key was used
  * improperly.
  */
-class StripeIdempotencyError extends StripeError {}
+export class StripeIdempotencyError extends StripeError {}
 
 /**
  * InvalidGrantError is raised when a specified code doesn't exist, is
@@ -154,25 +157,9 @@ class StripeIdempotencyError extends StripeError {}
  * exist, or doesn't belong to you; or if an API key's mode (live or test)
  * doesn't match the mode of a code or refresh token.
  */
-class StripeInvalidGrantError extends StripeError {}
+export class StripeInvalidGrantError extends StripeError {}
 
 /**
  * Any other error from Stripe not specifically captured above
  */
-class StripeUnknownError extends StripeError {}
-
-export = {
-  generate: StripeError.generate,
-  StripeError: StripeError,
-  StripeCardError: StripeCardError,
-  StripeInvalidRequestError: StripeInvalidRequestError,
-  StripeAPIError: StripeAPIError,
-  StripeAuthenticationError: StripeAuthenticationError,
-  StripePermissionError: StripePermissionError,
-  StripeRateLimitError: StripeRateLimitError,
-  StripeConnectionError: StripeConnectionError,
-  StripeSignatureVerificationError: StripeSignatureVerificationError,
-  StripeIdempotencyError: StripeIdempotencyError,
-  StripeInvalidGrantError: StripeInvalidGrantError,
-  StripeUnknownError: StripeUnknownError,
-};
+export class StripeUnknownError extends StripeError {}
diff --git a/src/RequestSender.ts b/src/RequestSender.ts
index 979ce926..ba9012bf 100644
--- a/src/RequestSender.ts
+++ b/src/RequestSender.ts
@@ -1,19 +1,22 @@
-import _Error = require('./Error');
-import utils = require('./utils');
-const {
+import {
   StripeAPIError,
   StripeAuthenticationError,
   StripeConnectionError,
   StripeError,
   StripePermissionError,
   StripeRateLimitError,
-} = _Error;
-
-const {HttpClient} = require('./net/HttpClient');
+} from './Error';
+import {
+  emitWarning,
+  normalizeHeaders,
+  removeNullish,
+  stringifyRequestData,
+} from './utils';
+import {HttpClient} from './net/HttpClient';
 
 const MAX_RETRY_AFTER_WAIT = 60;
 
-class RequestSender {
+export class RequestSender {
   protected _stripe: StripeObject;
   private readonly _maxBufferedRequestMetric: number;
 
@@ -41,7 +44,7 @@ class RequestSender {
     const requestEndTime = Date.now();
     const requestDurationMs = requestEndTime - requestEvent.request_start_time;
 
-    return utils.removeNullish({
+    return removeNullish({
       api_version: headers['stripe-version'] as string,
       account: headers['stripe-account'] as string,
       idempotency_key: headers['idempotency-key'] as string,
@@ -335,7 +338,7 @@ class RequestSender {
     // and fix these cases as they are semantically incorrect.
     if (methodHasPayload || contentLength) {
       if (!methodHasPayload) {
-        utils.emitWarning(
+        emitWarning(
           `${method} method had non-zero contentLength but no payload is expected for this verb`
         );
       }
@@ -343,9 +346,9 @@ class RequestSender {
     }
 
     return Object.assign(
-      utils.removeNullish(defaultHeaders),
+      removeNullish(defaultHeaders),
       // If the user supplied, say 'idempotency-key', override instead of appending by ensuring caps are the same.
-      utils.normalizeHeaders(userSuppliedHeaders)
+      normalizeHeaders(userSuppliedHeaders)
     );
   }
 
@@ -375,7 +378,7 @@ class RequestSender {
       if (
         this._stripe._prevRequestMetrics.length > this._maxBufferedRequestMetric
       ) {
-        utils.emitWarning(
+        emitWarning(
           'Request metrics buffer is full, dropping telemetry message.'
         );
       } else {
@@ -445,7 +448,7 @@ class RequestSender {
       const requestStartTime = Date.now();
 
       // @ts-ignore
-      const requestEvent: RequestEvent = utils.removeNullish({
+      const requestEvent: RequestEvent = removeNullish({
         api_version: apiVersion,
         account: headers['Stripe-Account'],
         idempotency_key: headers['Idempotency-Key'],
@@ -538,9 +541,7 @@ class RequestSender {
         prepareAndMakeRequest
       );
     } else {
-      prepareAndMakeRequest(null, utils.stringifyRequestData(data || {}));
+      prepareAndMakeRequest(null, stringifyRequestData(data || {}));
     }
   }
 }
-
-export = RequestSender;
diff --git a/src/ResourceNamespace.ts b/src/ResourceNamespace.ts
index b4d5238c..90fe611f 100644
--- a/src/ResourceNamespace.ts
+++ b/src/ResourceNamespace.ts
@@ -1,6 +1,5 @@
 // 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(
   this: StripeResourceNamespaceObject,
   stripe: StripeObject,
@@ -15,13 +14,11 @@ function ResourceNamespace(
   }
 }
 
-module.exports = function(
+export function resourceNamespace(
   namespace: string,
   resources: Array<StripeResourceObject>
 ): (stripe: StripeObject) => StripeResourceNamespaceObject {
   return function(stripe: StripeObject): StripeResourceNamespaceObject {
     return new (ResourceNamespace as any)(stripe, resources);
   };
-};
-
-module.exports.ResourceNamespace = ResourceNamespace;
+}
diff --git a/src/StripeEmitter.ts b/src/StripeEmitter.ts
index bc5ee842..573ff056 100644
--- a/src/StripeEmitter.ts
+++ b/src/StripeEmitter.ts
@@ -15,7 +15,7 @@ type Listener = (...args: any[]) => any;
 type ListenerWrapper = (event: _StripeEvent) => void;
 
 /** Minimal EventEmitter wrapper around EventTarget. */
-class StripeEmitter {
+export class StripeEmitter {
   eventTarget: EventTarget;
   listenerMapping: Map<Listener, ListenerWrapper>;
 
@@ -52,5 +52,3 @@ class StripeEmitter {
     return this.eventTarget.dispatchEvent(new _StripeEvent(eventName, data));
   }
 }
-
-export = StripeEmitter;
diff --git a/src/StripeMethod.ts b/src/StripeMethod.ts
index 0b0d2438..2b11d526 100644
--- a/src/StripeMethod.ts
+++ b/src/StripeMethod.ts
@@ -1,7 +1,5 @@
-import utils = require('./utils');
-import makeRequest = require('./RequestSender');
-import autoPagination = require('./autoPagination');
-const makeAutoPaginationMethods = autoPagination.makeAutoPaginationMethods;
+import {callbackifyPromiseWithTimeout, extractUrlParams} from './utils';
+import {makeAutoPaginationMethods} from './autoPagination';
 
 /**
  * Create an API method from the declared spec.
@@ -18,8 +16,12 @@ const makeAutoPaginationMethods = autoPagination.makeAutoPaginationMethods;
  * @param [spec.encode] Function for mutating input parameters to a method.
  *  Usefully for applying transforms to data on a per-method basis.
  * @param [spec.host] Hostname for the request.
+ *
+ * <!-- Public API accessible via Stripe.StripeResource.method -->
  */
-function stripeMethod(spec: MethodSpec): (...args: any[]) => Promise<any> {
+export function stripeMethod(
+  spec: MethodSpec
+): (...args: any[]) => Promise<any> {
   if (spec.path !== undefined && spec.fullPath !== undefined) {
     throw new Error(
       `Method spec specified both a 'path' (${spec.path}) and a 'fullPath' (${spec.fullPath}).`
@@ -28,11 +30,11 @@ function stripeMethod(spec: MethodSpec): (...args: any[]) => Promise<any> {
   return function(this: StripeResourceObject, ...args: any[]): Promise<any> {
     const callback = typeof args[args.length - 1] == 'function' && args.pop();
 
-    spec.urlParams = utils.extractUrlParams(
+    spec.urlParams = extractUrlParams(
       spec.fullPath || this.createResourcePathWithSymbols(spec.path || '')
     );
 
-    const requestPromise = utils.callbackifyPromiseWithTimeout(
+    const requestPromise = callbackifyPromiseWithTimeout(
       this._makeRequest(args, spec, {}),
       callback
     );
@@ -52,5 +54,3 @@ function stripeMethod(spec: MethodSpec): (...args: any[]) => Promise<any> {
     return requestPromise;
   };
 }
-
-export = stripeMethod;
diff --git a/src/StripeResource.ts b/src/StripeResource.ts
index ed657b73..bb0188c6 100644
--- a/src/StripeResource.ts
+++ b/src/StripeResource.ts
@@ -1,10 +1,17 @@
-import * as utils from './utils';
+import {
+  getDataFromArgs,
+  getOptionsFromArgs,
+  makeURLInterpolator,
+  protoExtend,
+  stringifyRequestData,
+} from './utils';
+import {stripeMethod} from './StripeMethod';
 
 // Provide extension mechanism for Stripe Resource Sub-Classes
-StripeResource.extend = utils.protoExtend;
+StripeResource.extend = protoExtend;
 
 // Expose method-creator
-StripeResource.method = require('./StripeMethod');
+StripeResource.method = stripeMethod;
 
 StripeResource.MAX_BUFFERED_REQUEST_METRICS = 100;
 
@@ -23,14 +30,14 @@ function StripeResource(
     );
   }
 
-  this.basePath = utils.makeURLInterpolator(
+  this.basePath = makeURLInterpolator(
     // @ts-ignore changing type of basePath
     this.basePath || stripe.getApiField('basePath')
   );
   // @ts-ignore changing type of path
   this.resourcePath = this.path;
   // @ts-ignore changing type of path
-  this.path = utils.makeURLInterpolator(this.path);
+  this.path = makeURLInterpolator(this.path);
 
   this.initialize(...arguments);
 }
@@ -109,7 +116,7 @@ StripeResource.prototype = {
     const encode = spec.encode || ((data): RequestData => data);
 
     const isUsingFullPath = !!spec.fullPath;
-    const commandPath: UrlInterpolator = utils.makeURLInterpolator(
+    const commandPath: UrlInterpolator = makeURLInterpolator(
       isUsingFullPath ? spec.fullPath! : spec.path || ''
     );
     // When using fullPath, we ignore the resource path as it should already be
@@ -135,9 +142,9 @@ StripeResource.prototype = {
     }, {});
 
     // Pull request data and options (headers, auth) from args.
-    const dataFromArgs = utils.getDataFromArgs(args);
+    const dataFromArgs = getDataFromArgs(args);
     const data = encode(Object.assign({}, dataFromArgs, overrideData));
-    const options = utils.getOptionsFromArgs(args);
+    const options = getOptionsFromArgs(args);
     const host = options.host || spec.host;
     const streaming = !!spec.streaming;
     // Validate that there are no more args.
@@ -209,7 +216,7 @@ StripeResource.prototype = {
       const path = [
         opts.requestPath,
         emptyQuery ? '' : '?',
-        utils.stringifyRequestData(opts.queryData),
+        stringifyRequestData(opts.queryData),
       ].join('');
 
       const {headers, settings} = opts;
@@ -228,4 +235,4 @@ StripeResource.prototype = {
   },
 } as StripeResourceObject;
 
-export = StripeResource;
+export {StripeResource};
diff --git a/src/Types.d.ts b/src/Types.d.ts
index 80ea9955..9b503097 100644
--- a/src/Types.d.ts
+++ b/src/Types.d.ts
@@ -1,7 +1,7 @@
 /* eslint-disable camelcase */
 type AppInfo = {name?: string} & Record<string, unknown>;
 type BufferedFile = {name: string; type: string; file: {data: Uint8Array}};
-type HttpClientResponseError = {code: number};
+type HttpClientResponseError = {code: string};
 type MethodSpec = {
   method: string;
   methodType: string;
@@ -155,7 +155,7 @@ type StripeObject = {
   _requestSender: RequestSender;
   _getPropsFromConfig: (config: Record<string, unknown>) => UserProvidedConfig;
   _clientId?: string;
-  _platformFunctions: import('./platform/PlatformFunctions');
+  _platformFunctions: import('./platform/PlatformFunctions').PlatformFunctions;
 };
 type RequestSender = {
   _request(
diff --git a/src/Webhooks.ts b/src/Webhooks.ts
index bc6977b7..b20ecb5a 100644
--- a/src/Webhooks.ts
+++ b/src/Webhooks.ts
@@ -1,7 +1,6 @@
-import CryptoProvider = require('./crypto/CryptoProvider');
-import _Error = require('./Error');
-import PlatformFunctions = require('./platform/PlatformFunctions');
-const {StripeError, StripeSignatureVerificationError} = _Error;
+import {StripeError, StripeSignatureVerificationError} from './Error';
+import {CryptoProvider} from './crypto/CryptoProvider';
+import {PlatformFunctions} from './platform/PlatformFunctions';
 
 type WebhookHeader = string | Uint8Array;
 type WebhookParsedHeader = {
@@ -61,7 +60,9 @@ type WebhookObject = {
   generateTestHeaderString: (opts: WebhookTestHeaderOptions) => string;
 };
 
-function createWebhooks(platformFunctions: PlatformFunctions): WebhookObject {
+export function createWebhooks(
+  platformFunctions: PlatformFunctions
+): WebhookObject {
   const Webhook: WebhookObject = {
     DEFAULT_TOLERANCE: 300, // 5 minutes
     // @ts-ignore
@@ -402,5 +403,3 @@ function createWebhooks(platformFunctions: PlatformFunctions): WebhookObject {
 
   return Webhook;
 }
-
-export = createWebhooks;
diff --git a/src/autoPagination.ts b/src/autoPagination.ts
index 32905db2..751f1fd3 100644
--- a/src/autoPagination.ts
+++ b/src/autoPagination.ts
@@ -1,4 +1,4 @@
-import utils = require('./utils');
+import {callbackifyPromiseWithTimeout, getDataFromArgs} from './utils';
 
 type PromiseCache = {
   currentPromise: Promise<any> | undefined | null;
@@ -37,7 +37,7 @@ type AutoPaginationMethods = {
   return: () => void;
 };
 
-function makeAutoPaginationMethods(
+export function makeAutoPaginationMethods(
   self: StripeResourceObject,
   requestArgs: RequestArgs,
   spec: MethodSpec,
@@ -135,10 +135,6 @@ function makeAutoPaginationMethods(
   return autoPaginationMethods;
 }
 
-export = {
-  makeAutoPaginationMethods: makeAutoPaginationMethods,
-};
-
 /**
  * ----------------
  * Private Helpers:
@@ -256,7 +252,7 @@ function makeAutoPagingEach(
       // @ts-ignore we might need a null check
       onItem
     );
-    return utils.callbackifyPromiseWithTimeout(autoPagePromise, onDone);
+    return callbackifyPromiseWithTimeout(autoPagePromise, onDone);
   } as AutoPagingEach;
 }
 
@@ -292,7 +288,7 @@ function makeAutoPagingToArray(
         .catch(reject);
     });
     // @ts-ignore
-    return utils.callbackifyPromiseWithTimeout(promise, onDone);
+    return callbackifyPromiseWithTimeout(promise, onDone);
   };
 }
 
@@ -330,7 +326,7 @@ function wrapAsyncIteratorWithCallback(
 
 function isReverseIteration(requestArgs: RequestArgs): boolean {
   const args = [].slice.call(requestArgs);
-  const dataFromArgs = utils.getDataFromArgs(args);
+  const dataFromArgs = getDataFromArgs(args);
 
   return !!dataFromArgs.ending_before;
 }
diff --git a/src/crypto/CryptoProvider.ts b/src/crypto/CryptoProvider.ts
index bd7387c8..feba8c3b 100644
--- a/src/crypto/CryptoProvider.ts
+++ b/src/crypto/CryptoProvider.ts
@@ -2,7 +2,7 @@
  * Interface encapsulating the various crypto computations used by the library,
  * allowing pluggable underlying crypto implementations.
  */
-class CryptoProvider {
+export class CryptoProvider {
   /**
    * Computes a SHA-256 HMAC given a secret and a payload (encoded in UTF-8).
    * The output HMAC should be encoded in hexadecimal.
@@ -30,5 +30,3 @@ class CryptoProvider {
     throw new Error('computeHMACSignatureAsync not implemented.');
   }
 }
-
-export = CryptoProvider;
diff --git a/src/crypto/NodeCryptoProvider.ts b/src/crypto/NodeCryptoProvider.ts
index 4521bc91..ce6f05c3 100644
--- a/src/crypto/NodeCryptoProvider.ts
+++ b/src/crypto/NodeCryptoProvider.ts
@@ -1,11 +1,10 @@
-import crypto = require('crypto');
-
-import CryptoProvider = require('./CryptoProvider');
+import * as crypto from 'crypto';
+import {CryptoProvider} from './CryptoProvider';
 
 /**
  * `CryptoProvider which uses the Node `crypto` package for its computations.
  */
-class NodeCryptoProvider extends CryptoProvider {
+export class NodeCryptoProvider extends CryptoProvider {
   /** @override */
   computeHMACSignature(payload: string, secret: string): string {
     return crypto
@@ -23,5 +22,3 @@ class NodeCryptoProvider extends CryptoProvider {
     return signature;
   }
 }
-
-export = NodeCryptoProvider;
diff --git a/src/crypto/SubtleCryptoProvider.ts b/src/crypto/SubtleCryptoProvider.ts
index 886ac469..54da803f 100644
--- a/src/crypto/SubtleCryptoProvider.ts
+++ b/src/crypto/SubtleCryptoProvider.ts
@@ -1,11 +1,11 @@
-import CryptoProvider = require('./CryptoProvider');
+import {CryptoProvider} from './CryptoProvider';
 
 /**
  * `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
  *
  * This only supports asynchronous operations.
  */
-class SubtleCryptoProvider extends CryptoProvider {
+export class SubtleCryptoProvider extends CryptoProvider {
   subtleCrypto: SubtleCrypto;
 
   constructor(subtleCrypto?: SubtleCrypto) {
@@ -68,5 +68,3 @@ const byteHexMapping = new Array(256);
 for (let i = 0; i < byteHexMapping.length; i++) {
   byteHexMapping[i] = i.toString(16).padStart(2, '0');
 }
-
-export = SubtleCryptoProvider;
diff --git a/src/multipart.ts b/src/multipart.ts
index 29abbbb9..aea51ae8 100644
--- a/src/multipart.ts
+++ b/src/multipart.ts
@@ -1,5 +1,4 @@
-import utils = require('./utils');
-import _Error = require('./Error');
+import {flattenAndStringify, stringifyRequestData} from './utils';
 
 type MultipartCallbackReturn = any;
 type MultipartCallback = (
@@ -38,7 +37,7 @@ const multipartDataGenerator = (
     return `"${s.replace(/"|"/g, '%22').replace(/\r\n|\r|\n/g, ' ')}"`;
   }
 
-  const flattenedData = utils.flattenAndStringify(data);
+  const flattenedData = flattenAndStringify(data);
 
   for (const k in flattenedData) {
     const v = flattenedData[k];
@@ -78,7 +77,7 @@ function multipartRequestDataProcessor(
   data = data || {};
 
   if (method !== 'POST') {
-    return callback(null, utils.stringifyRequestData(data));
+    return callback(null, stringifyRequestData(data));
   }
 
   this._stripe._platformFunctions
diff --git a/src/net/FetchHttpClient.ts b/src/net/FetchHttpClient.ts
index 6e4facec..f3056795 100644
--- a/src/net/FetchHttpClient.ts
+++ b/src/net/FetchHttpClient.ts
@@ -1,5 +1,4 @@
-import _HttpClient = require('./HttpClient');
-const {HttpClient, HttpClientResponse} = _HttpClient;
+import {HttpClient, HttpClientResponse} from './HttpClient';
 
 /**
  * HTTP client which uses a `fetch` function to issue requests.
@@ -9,10 +8,10 @@ const {HttpClient, HttpClientResponse} = _HttpClient;
  * Fetch API. As an example, this could be the function provided by the
  * node-fetch package (https://github.com/node-fetch/node-fetch).
  */
-class FetchHttpClient extends HttpClient implements HttpClientInterface {
-  _fetchFn: typeof fetch;
+export class FetchHttpClient extends HttpClient implements HttpClientInterface {
+  _fetchFn?: typeof fetch;
 
-  constructor(fetchFn: typeof fetch) {
+  constructor(fetchFn?: typeof fetch) {
     super();
     this._fetchFn = fetchFn;
   }
@@ -90,7 +89,7 @@ class FetchHttpClient extends HttpClient implements HttpClientInterface {
   }
 }
 
-class FetchHttpClientResponse extends HttpClientResponse
+export class FetchHttpClientResponse extends HttpClientResponse
   implements HttpClientResponseInterface {
   _res: Response;
 
@@ -141,5 +140,3 @@ class FetchHttpClientResponse extends HttpClientResponse
     return headersObj;
   }
 }
-
-export = {FetchHttpClient, FetchHttpClientResponse};
diff --git a/src/net/HttpClient.ts b/src/net/HttpClient.ts
index 56c67090..ad2b2bb7 100644
--- a/src/net/HttpClient.ts
+++ b/src/net/HttpClient.ts
@@ -9,7 +9,7 @@ type TimeoutError = TypeError & {code?: string};
  * 2. A client class which extends HttpClient and implements all methods,
  *    returning their own response class when making requests.
  */
-class HttpClient implements HttpClientInterface {
+export class HttpClient implements HttpClientInterface {
   static CONNECTION_CLOSED_ERROR_CODES: string[];
   static TIMEOUT_ERROR_CODE: string;
 
@@ -41,10 +41,11 @@ class HttpClient implements HttpClientInterface {
   }
 }
 
+// Public API accessible via Stripe.HttpClient
 HttpClient.CONNECTION_CLOSED_ERROR_CODES = ['ECONNRESET', 'EPIPE'];
 HttpClient.TIMEOUT_ERROR_CODE = 'ETIMEDOUT';
 
-class HttpClientResponse implements HttpClientResponseInterface {
+export class HttpClientResponse implements HttpClientResponseInterface {
   _statusCode: number;
   _headers: ResponseHeaders;
 
@@ -73,5 +74,3 @@ class HttpClientResponse implements HttpClientResponseInterface {
     throw new Error('toJSON not implemented.');
   }
 }
-
-export = {HttpClient, HttpClientResponse};
diff --git a/src/net/NodeHttpClient.ts b/src/net/NodeHttpClient.ts
index 93b37a26..b7853286 100644
--- a/src/net/NodeHttpClient.ts
+++ b/src/net/NodeHttpClient.ts
@@ -1,8 +1,6 @@
-import http = require('http');
-import https = require('https');
-
-import _HttpClient = require('./HttpClient');
-const {HttpClient, HttpClientResponse} = _HttpClient;
+import * as http from 'http';
+import * as https from 'https';
+import {HttpClient, HttpClientResponse} from './HttpClient';
 
 const defaultHttpAgent = new http.Agent({keepAlive: true});
 const defaultHttpsAgent = new https.Agent({keepAlive: true});
@@ -11,10 +9,10 @@ const defaultHttpsAgent = new https.Agent({keepAlive: true});
  * HTTP client which uses the Node `http` and `https` packages to issue
  * requests.`
  */
-class NodeHttpClient extends HttpClient {
-  _agent: http.Agent | https.Agent;
+export class NodeHttpClient extends HttpClient {
+  _agent?: http.Agent | https.Agent | undefined;
 
-  constructor(agent: http.Agent | https.Agent) {
+  constructor(agent?: http.Agent | https.Agent) {
     super();
     this._agent = agent;
   }
@@ -88,7 +86,7 @@ class NodeHttpClient extends HttpClient {
   }
 }
 
-class NodeHttpClientResponse extends HttpClientResponse
+export class NodeHttpClientResponse extends HttpClientResponse
   implements HttpClientResponseInterface {
   _res: http.IncomingMessage;
 
@@ -128,5 +126,3 @@ class NodeHttpClientResponse extends HttpClientResponse
     });
   }
 }
-
-export = {NodeHttpClient, NodeHttpClientResponse};
diff --git a/src/platform/NodePlatformFunctions.ts b/src/platform/NodePlatformFunctions.ts
index 668cfd48..8e788b21 100644
--- a/src/platform/NodePlatformFunctions.ts
+++ b/src/platform/NodePlatformFunctions.ts
@@ -1,23 +1,20 @@
-import crypto = require('crypto');
-import EventEmitter = require('events');
-import _Error = require('../Error');
-const StripeError = _Error.StripeError;
-import utils = require('../utils');
-import PlatformFunctions = require('./PlatformFunctions');
-import http = require('http');
-import _HttpClient = require('../net/HttpClient');
-const HttpClient = _HttpClient.HttpClient;
-import _NodeHttpClient = require('../net/NodeHttpClient');
-const NodeHttpClient = _NodeHttpClient.NodeHttpClient;
-import NodeCryptoProvider = require('../crypto/NodeCryptoProvider');
-import CryptoProvider = require('../crypto/CryptoProvider');
+import * as crypto from 'crypto';
+import * as http from 'http';
+import {CryptoProvider} from '../crypto/CryptoProvider';
+import {EventEmitter} from 'events';
+import {HttpClient} from '../net/HttpClient';
+import {NodeCryptoProvider} from '../crypto/NodeCryptoProvider';
+import {NodeHttpClient} from '../net/NodeHttpClient';
+import {PlatformFunctions} from './PlatformFunctions';
+import {StripeError} from '../Error';
+import {concat} from '../utils';
 
 class StreamProcessingError extends StripeError {}
 
 /**
  * Specializes WebPlatformFunctions using APIs available in Node.js.
  */
-class NodePlatformFunctions extends PlatformFunctions {
+export class NodePlatformFunctions extends PlatformFunctions {
   /** For mocking in tests */
   _exec: any;
   _UNAME_CACHE: Promise<string | null> | null;
@@ -112,7 +109,7 @@ class NodePlatformFunctions extends PlatformFunctions {
         .once('end', () => {
           // @ts-ignore
           const bufferData: BufferedFile = Object.assign({}, data);
-          bufferData.file.data = utils.concat(bufferArray);
+          bufferData.file.data = concat(bufferArray);
           resolve(bufferData);
         })
         .on('error', (err: Error) => {
@@ -128,15 +125,13 @@ class NodePlatformFunctions extends PlatformFunctions {
   }
 
   /** @override */
-  createNodeHttpClient(agent: http.Agent | null): typeof HttpClient {
-    // @ts-ignore
+  createNodeHttpClient(agent?: http.Agent): HttpClient {
     return new NodeHttpClient(agent);
   }
 
   /** @override */
-  createDefaultHttpClient(): typeof HttpClient {
-    // @ts-ignore
-    return new NodeHttpClient(null);
+  createDefaultHttpClient(): HttpClient {
+    return new NodeHttpClient();
   }
 
   /** @override */
@@ -149,5 +144,3 @@ class NodePlatformFunctions extends PlatformFunctions {
     return this.createNodeCryptoProvider();
   }
 }
-
-export = NodePlatformFunctions;
diff --git a/src/platform/PlatformFunctions.ts b/src/platform/PlatformFunctions.ts
index 49bb14cf..b07289d0 100644
--- a/src/platform/PlatformFunctions.ts
+++ b/src/platform/PlatformFunctions.ts
@@ -1,18 +1,16 @@
-import EventEmitter = require('events');
-import StripeEmitter = require('../StripeEmitter');
-import http = require('http');
-import _HttpClient = require('../net/HttpClient');
-const HttpClient = _HttpClient.HttpClient;
-import _FetchHttpClient = require('../net/FetchHttpClient');
-const FetchHttpClient = _FetchHttpClient.FetchHttpClient;
-import SubtleCryptoProvider = require('../crypto/SubtleCryptoProvider');
-import CryptoProvider = require('../crypto/CryptoProvider');
+import * as http from 'http';
+import {CryptoProvider} from '../crypto/CryptoProvider';
+import {EventEmitter} from 'events';
+import {FetchHttpClient} from '../net/FetchHttpClient';
+import {HttpClient} from '../net/HttpClient';
+import {StripeEmitter} from '../StripeEmitter';
+import {SubtleCryptoProvider} from '../crypto/SubtleCryptoProvider';
 
 /**
  * Interface encapsulating various utility functions whose
  * implementations depend on the platform / JS runtime.
  */
-class PlatformFunctions {
+export class PlatformFunctions {
   _fetchFn: any | null;
   _agent: http.Agent | null;
 
@@ -76,7 +74,7 @@ class PlatformFunctions {
    * Creates an HTTP client which uses the Node `http` and `https` packages
    * to issue requests.
    */
-  createNodeHttpClient(agent?: http.Agent | null): typeof HttpClient {
+  createNodeHttpClient(agent?: http.Agent): HttpClient {
     throw new Error('createNodeHttpClient not implemented.');
   }
 
@@ -87,15 +85,14 @@ class PlatformFunctions {
    * A fetch function can optionally be passed in as a parameter. If none is
    * passed, will default to the default `fetch` function in the global scope.
    */
-  createFetchHttpClient(fetchFn?: typeof fetch | null): typeof HttpClient {
-    // @ts-ignore
+  createFetchHttpClient(fetchFn?: typeof fetch): HttpClient {
     return new FetchHttpClient(fetchFn);
   }
 
   /**
    * Creates an HTTP client using runtime-specific APIs.
    */
-  createDefaultHttpClient(): typeof HttpClient {
+  createDefaultHttpClient(): HttpClient {
     throw new Error('createDefaultHttpClient not implemented.');
   }
 
@@ -119,5 +116,3 @@ class PlatformFunctions {
     throw new Error('createDefaultCryptoProvider not implemented.');
   }
 }
-
-export = PlatformFunctions;
diff --git a/src/platform/WebPlatformFunctions.ts b/src/platform/WebPlatformFunctions.ts
index f0028624..64c971e0 100644
--- a/src/platform/WebPlatformFunctions.ts
+++ b/src/platform/WebPlatformFunctions.ts
@@ -1,13 +1,12 @@
-import StripeEmitter = require('../StripeEmitter');
-import PlatformFunctions = require('./PlatformFunctions');
-import _HttpClient = require('../net/HttpClient');
-import CryptoProvider = require('../crypto/CryptoProvider');
-const HttpClient = _HttpClient.HttpClient;
+import {CryptoProvider} from '../crypto/CryptoProvider';
+import {HttpClient} from '../net/HttpClient';
+import {PlatformFunctions} from './PlatformFunctions';
+import {StripeEmitter} from '../StripeEmitter';
 
 /**
  * Specializes WebPlatformFunctions using APIs available in Web workers.
  */
-class WebPlatformFunctions extends PlatformFunctions {
+export class WebPlatformFunctions extends PlatformFunctions {
   /** @override */
   getUname(): Promise<string | null> {
     return Promise.resolve(null);
@@ -31,14 +30,14 @@ class WebPlatformFunctions extends PlatformFunctions {
   }
 
   /** @override */
-  createNodeHttpClient(): typeof HttpClient {
+  createNodeHttpClient(): HttpClient {
     throw new Error(
       'Stripe: `createNodeHttpClient()` is not available in non-Node environments. Please use `createFetchHttpClient()` instead.'
     );
   }
 
   /** @override */
-  createDefaultHttpClient(): typeof HttpClient {
+  createDefaultHttpClient(): HttpClient {
     return super.createFetchHttpClient();
   }
 
@@ -54,5 +53,3 @@ class WebPlatformFunctions extends PlatformFunctions {
     return this.createSubtleCryptoProvider();
   }
 }
-
-export = WebPlatformFunctions;
diff --git a/src/resources.js b/src/resources.js
index 3b24b4f8..9653839c 100644
--- a/src/resources.js
+++ b/src/resources.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const resourceNamespace = require('./ResourceNamespace');
+const {resourceNamespace} = require('./ResourceNamespace');
 
 module.exports = {
   // Support Accounts for consistency, Account for backwards compatibility
diff --git a/src/resources/AccountLinks.js b/src/resources/AccountLinks.js
index 713304f7..ee82451f 100644
--- a/src/resources/AccountLinks.js
+++ b/src/resources/AccountLinks.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Accounts.js b/src/resources/Accounts.js
index e31178ae..2573b4aa 100644
--- a/src/resources/Accounts.js
+++ b/src/resources/Accounts.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 // Since path can either be `account` or `accounts`, support both through stripeMethod path;
diff --git a/src/resources/ApplePayDomains.js b/src/resources/ApplePayDomains.js
index 363e375f..bb40bafd 100644
--- a/src/resources/ApplePayDomains.js
+++ b/src/resources/ApplePayDomains.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/ApplicationFees.js b/src/resources/ApplicationFees.js
index 919cc718..36825fbc 100644
--- a/src/resources/ApplicationFees.js
+++ b/src/resources/ApplicationFees.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Apps/Secrets.js b/src/resources/Apps/Secrets.js
index 7003cb2a..150f8cf7 100644
--- a/src/resources/Apps/Secrets.js
+++ b/src/resources/Apps/Secrets.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Balance.js b/src/resources/Balance.js
index 8cb2c44b..e1bf5503 100644
--- a/src/resources/Balance.js
+++ b/src/resources/Balance.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/BalanceTransactions.js b/src/resources/BalanceTransactions.js
index 4e0c9d0e..7741d336 100644
--- a/src/resources/BalanceTransactions.js
+++ b/src/resources/BalanceTransactions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/BillingPortal/Configurations.js b/src/resources/BillingPortal/Configurations.js
index cda7d157..ea6386aa 100644
--- a/src/resources/BillingPortal/Configurations.js
+++ b/src/resources/BillingPortal/Configurations.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/BillingPortal/Sessions.js b/src/resources/BillingPortal/Sessions.js
index b2dbd1c9..cf685931 100644
--- a/src/resources/BillingPortal/Sessions.js
+++ b/src/resources/BillingPortal/Sessions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Charges.js b/src/resources/Charges.js
index 87b18dc1..cb9adfe0 100644
--- a/src/resources/Charges.js
+++ b/src/resources/Charges.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Checkout/Sessions.js b/src/resources/Checkout/Sessions.js
index cf9bfb24..65cba464 100644
--- a/src/resources/Checkout/Sessions.js
+++ b/src/resources/Checkout/Sessions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/CountrySpecs.js b/src/resources/CountrySpecs.js
index f21b9ab4..8b9ebf8b 100644
--- a/src/resources/CountrySpecs.js
+++ b/src/resources/CountrySpecs.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Coupons.js b/src/resources/Coupons.js
index 3b62c60e..84ec3eea 100644
--- a/src/resources/Coupons.js
+++ b/src/resources/Coupons.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/CreditNotes.js b/src/resources/CreditNotes.js
index 70340b08..6a63c47d 100644
--- a/src/resources/CreditNotes.js
+++ b/src/resources/CreditNotes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Customers.js b/src/resources/Customers.js
index f44166ef..d5719b99 100644
--- a/src/resources/Customers.js
+++ b/src/resources/Customers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Disputes.js b/src/resources/Disputes.js
index d40c7a8f..8edb4ed8 100644
--- a/src/resources/Disputes.js
+++ b/src/resources/Disputes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/EphemeralKeys.js b/src/resources/EphemeralKeys.js
index 45c632b7..2324a5e5 100644
--- a/src/resources/EphemeralKeys.js
+++ b/src/resources/EphemeralKeys.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Events.js b/src/resources/Events.js
index cb0b5ee9..bc1441f2 100644
--- a/src/resources/Events.js
+++ b/src/resources/Events.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/ExchangeRates.js b/src/resources/ExchangeRates.js
index bd6aec6b..1ad0c89c 100644
--- a/src/resources/ExchangeRates.js
+++ b/src/resources/ExchangeRates.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/FileLinks.js b/src/resources/FileLinks.js
index 0cc3afe7..8c8a0ab7 100644
--- a/src/resources/FileLinks.js
+++ b/src/resources/FileLinks.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Files.js b/src/resources/Files.js
index fbe9ce87..ec853046 100644
--- a/src/resources/Files.js
+++ b/src/resources/Files.js
@@ -3,7 +3,7 @@
 'use strict';
 
 const {multipartRequestDataProcessor} = require('../multipart');
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/FinancialConnections/Accounts.js b/src/resources/FinancialConnections/Accounts.js
index e795b228..dbe5e3a5 100644
--- a/src/resources/FinancialConnections/Accounts.js
+++ b/src/resources/FinancialConnections/Accounts.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/FinancialConnections/Sessions.js b/src/resources/FinancialConnections/Sessions.js
index 077390c4..12a07905 100644
--- a/src/resources/FinancialConnections/Sessions.js
+++ b/src/resources/FinancialConnections/Sessions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Identity/VerificationReports.js b/src/resources/Identity/VerificationReports.js
index 6c8734c8..babca4e5 100644
--- a/src/resources/Identity/VerificationReports.js
+++ b/src/resources/Identity/VerificationReports.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Identity/VerificationSessions.js b/src/resources/Identity/VerificationSessions.js
index 47f442ba..e285c11c 100644
--- a/src/resources/Identity/VerificationSessions.js
+++ b/src/resources/Identity/VerificationSessions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/InvoiceItems.js b/src/resources/InvoiceItems.js
index 715c07e8..3eda4eb0 100644
--- a/src/resources/InvoiceItems.js
+++ b/src/resources/InvoiceItems.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Invoices.js b/src/resources/Invoices.js
index 85b3fc58..aa0f8a4b 100644
--- a/src/resources/Invoices.js
+++ b/src/resources/Invoices.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Issuing/Authorizations.js b/src/resources/Issuing/Authorizations.js
index 78afe9a4..7596d410 100644
--- a/src/resources/Issuing/Authorizations.js
+++ b/src/resources/Issuing/Authorizations.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Issuing/Cardholders.js b/src/resources/Issuing/Cardholders.js
index bb00cde2..cfcab6b9 100644
--- a/src/resources/Issuing/Cardholders.js
+++ b/src/resources/Issuing/Cardholders.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Issuing/Cards.js b/src/resources/Issuing/Cards.js
index f197403f..6ca97110 100644
--- a/src/resources/Issuing/Cards.js
+++ b/src/resources/Issuing/Cards.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Issuing/Disputes.js b/src/resources/Issuing/Disputes.js
index 67eab915..8b0d641c 100644
--- a/src/resources/Issuing/Disputes.js
+++ b/src/resources/Issuing/Disputes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Issuing/Transactions.js b/src/resources/Issuing/Transactions.js
index eee0eb82..1d3f8feb 100644
--- a/src/resources/Issuing/Transactions.js
+++ b/src/resources/Issuing/Transactions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Mandates.js b/src/resources/Mandates.js
index 678e732d..5aebb1a4 100644
--- a/src/resources/Mandates.js
+++ b/src/resources/Mandates.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/OAuth.js b/src/resources/OAuth.js
index 70ce4a23..287eeea7 100644
--- a/src/resources/OAuth.js
+++ b/src/resources/OAuth.js
@@ -1,8 +1,8 @@
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
-const utils = require('../utils');
+const {stringifyRequestData} = require('../utils');
 
 const oAuthHost = 'connect.stripe.com';
 
@@ -32,7 +32,7 @@ module.exports = StripeResource.extend({
       params.scope = 'read_write';
     }
 
-    return `https://${oAuthHost}/${path}?${utils.stringifyRequestData(params)}`;
+    return `https://${oAuthHost}/${path}?${stringifyRequestData(params)}`;
   },
 
   token: stripeMethod({
diff --git a/src/resources/PaymentIntents.js b/src/resources/PaymentIntents.js
index a90d20f2..4c66b2aa 100644
--- a/src/resources/PaymentIntents.js
+++ b/src/resources/PaymentIntents.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/PaymentLinks.js b/src/resources/PaymentLinks.js
index 2eb101ca..e7717d68 100644
--- a/src/resources/PaymentLinks.js
+++ b/src/resources/PaymentLinks.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/PaymentMethods.js b/src/resources/PaymentMethods.js
index 682d1bae..7766ebd0 100644
--- a/src/resources/PaymentMethods.js
+++ b/src/resources/PaymentMethods.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Payouts.js b/src/resources/Payouts.js
index 0fa97179..448c92e5 100644
--- a/src/resources/Payouts.js
+++ b/src/resources/Payouts.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Plans.js b/src/resources/Plans.js
index c9032c1a..194fffd9 100644
--- a/src/resources/Plans.js
+++ b/src/resources/Plans.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Prices.js b/src/resources/Prices.js
index e290429e..f6202fdc 100644
--- a/src/resources/Prices.js
+++ b/src/resources/Prices.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Products.js b/src/resources/Products.js
index 5a995c89..11ab5828 100644
--- a/src/resources/Products.js
+++ b/src/resources/Products.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/PromotionCodes.js b/src/resources/PromotionCodes.js
index be942e99..912bb1b2 100644
--- a/src/resources/PromotionCodes.js
+++ b/src/resources/PromotionCodes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Quotes.js b/src/resources/Quotes.js
index 0631c6f1..36098f2d 100644
--- a/src/resources/Quotes.js
+++ b/src/resources/Quotes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Radar/EarlyFraudWarnings.js b/src/resources/Radar/EarlyFraudWarnings.js
index 4e38d1c6..3a4166b3 100644
--- a/src/resources/Radar/EarlyFraudWarnings.js
+++ b/src/resources/Radar/EarlyFraudWarnings.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Radar/ValueListItems.js b/src/resources/Radar/ValueListItems.js
index df0b8c98..65303e0f 100644
--- a/src/resources/Radar/ValueListItems.js
+++ b/src/resources/Radar/ValueListItems.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Radar/ValueLists.js b/src/resources/Radar/ValueLists.js
index 68025810..5c9275bd 100644
--- a/src/resources/Radar/ValueLists.js
+++ b/src/resources/Radar/ValueLists.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Refunds.js b/src/resources/Refunds.js
index 380688d9..c60d5bad 100644
--- a/src/resources/Refunds.js
+++ b/src/resources/Refunds.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Reporting/ReportRuns.js b/src/resources/Reporting/ReportRuns.js
index c3ecf96c..47001783 100644
--- a/src/resources/Reporting/ReportRuns.js
+++ b/src/resources/Reporting/ReportRuns.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Reporting/ReportTypes.js b/src/resources/Reporting/ReportTypes.js
index 48e08548..7f8479b0 100644
--- a/src/resources/Reporting/ReportTypes.js
+++ b/src/resources/Reporting/ReportTypes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Reviews.js b/src/resources/Reviews.js
index f9b515b4..1c210fc9 100644
--- a/src/resources/Reviews.js
+++ b/src/resources/Reviews.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/SetupAttempts.js b/src/resources/SetupAttempts.js
index 7076944e..238be555 100644
--- a/src/resources/SetupAttempts.js
+++ b/src/resources/SetupAttempts.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/SetupIntents.js b/src/resources/SetupIntents.js
index 507c8c9b..edbe717b 100644
--- a/src/resources/SetupIntents.js
+++ b/src/resources/SetupIntents.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/ShippingRates.js b/src/resources/ShippingRates.js
index a24e8346..e447a5a2 100644
--- a/src/resources/ShippingRates.js
+++ b/src/resources/ShippingRates.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Sigma/ScheduledQueryRuns.js b/src/resources/Sigma/ScheduledQueryRuns.js
index 0396103a..064a0a4e 100644
--- a/src/resources/Sigma/ScheduledQueryRuns.js
+++ b/src/resources/Sigma/ScheduledQueryRuns.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Sources.js b/src/resources/Sources.js
index 258245ce..a4754565 100644
--- a/src/resources/Sources.js
+++ b/src/resources/Sources.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/SubscriptionItems.js b/src/resources/SubscriptionItems.js
index a58a6e45..a1bee1cc 100644
--- a/src/resources/SubscriptionItems.js
+++ b/src/resources/SubscriptionItems.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/SubscriptionSchedules.js b/src/resources/SubscriptionSchedules.js
index 9932c3fa..a391a6cd 100644
--- a/src/resources/SubscriptionSchedules.js
+++ b/src/resources/SubscriptionSchedules.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Subscriptions.js b/src/resources/Subscriptions.js
index 7f8f5eb8..b348b1ae 100644
--- a/src/resources/Subscriptions.js
+++ b/src/resources/Subscriptions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TaxCodes.js b/src/resources/TaxCodes.js
index 828617b2..b7f64cab 100644
--- a/src/resources/TaxCodes.js
+++ b/src/resources/TaxCodes.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TaxRates.js b/src/resources/TaxRates.js
index dbe45632..7cdaaf58 100644
--- a/src/resources/TaxRates.js
+++ b/src/resources/TaxRates.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Terminal/Configurations.js b/src/resources/Terminal/Configurations.js
index efdf67cc..2fb55a25 100644
--- a/src/resources/Terminal/Configurations.js
+++ b/src/resources/Terminal/Configurations.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Terminal/ConnectionTokens.js b/src/resources/Terminal/ConnectionTokens.js
index d210bb93..9f74bade 100644
--- a/src/resources/Terminal/ConnectionTokens.js
+++ b/src/resources/Terminal/ConnectionTokens.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Terminal/Locations.js b/src/resources/Terminal/Locations.js
index 3d87dce2..81002323 100644
--- a/src/resources/Terminal/Locations.js
+++ b/src/resources/Terminal/Locations.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Terminal/Readers.js b/src/resources/Terminal/Readers.js
index 554449db..e7a42f39 100644
--- a/src/resources/Terminal/Readers.js
+++ b/src/resources/Terminal/Readers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Tokens.js b/src/resources/Tokens.js
index b1a5ae07..e4374e24 100644
--- a/src/resources/Tokens.js
+++ b/src/resources/Tokens.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Topups.js b/src/resources/Topups.js
index 31c005d9..7892b06d 100644
--- a/src/resources/Topups.js
+++ b/src/resources/Topups.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Transfers.js b/src/resources/Transfers.js
index 5a360257..fefa52ad 100644
--- a/src/resources/Transfers.js
+++ b/src/resources/Transfers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/CreditReversals.js b/src/resources/Treasury/CreditReversals.js
index 95269366..2d156f49 100644
--- a/src/resources/Treasury/CreditReversals.js
+++ b/src/resources/Treasury/CreditReversals.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/DebitReversals.js b/src/resources/Treasury/DebitReversals.js
index abbab869..b6d0c360 100644
--- a/src/resources/Treasury/DebitReversals.js
+++ b/src/resources/Treasury/DebitReversals.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/FinancialAccounts.js b/src/resources/Treasury/FinancialAccounts.js
index 0a1a47ba..6f1662e8 100644
--- a/src/resources/Treasury/FinancialAccounts.js
+++ b/src/resources/Treasury/FinancialAccounts.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/InboundTransfers.js b/src/resources/Treasury/InboundTransfers.js
index 84ecb300..ce5f63d2 100644
--- a/src/resources/Treasury/InboundTransfers.js
+++ b/src/resources/Treasury/InboundTransfers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/OutboundPayments.js b/src/resources/Treasury/OutboundPayments.js
index b4c61918..568b587a 100644
--- a/src/resources/Treasury/OutboundPayments.js
+++ b/src/resources/Treasury/OutboundPayments.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/OutboundTransfers.js b/src/resources/Treasury/OutboundTransfers.js
index b5dfa874..d313c953 100644
--- a/src/resources/Treasury/OutboundTransfers.js
+++ b/src/resources/Treasury/OutboundTransfers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/ReceivedCredits.js b/src/resources/Treasury/ReceivedCredits.js
index 160f659c..c5c1278b 100644
--- a/src/resources/Treasury/ReceivedCredits.js
+++ b/src/resources/Treasury/ReceivedCredits.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/ReceivedDebits.js b/src/resources/Treasury/ReceivedDebits.js
index b946b42e..e31d9817 100644
--- a/src/resources/Treasury/ReceivedDebits.js
+++ b/src/resources/Treasury/ReceivedDebits.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/TransactionEntries.js b/src/resources/Treasury/TransactionEntries.js
index 067109bd..a0bd6858 100644
--- a/src/resources/Treasury/TransactionEntries.js
+++ b/src/resources/Treasury/TransactionEntries.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/Treasury/Transactions.js b/src/resources/Treasury/Transactions.js
index db1c5788..c2611b89 100644
--- a/src/resources/Treasury/Transactions.js
+++ b/src/resources/Treasury/Transactions.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/WebhookEndpoints.js b/src/resources/WebhookEndpoints.js
index b98d09e9..3e577e97 100644
--- a/src/resources/WebhookEndpoints.js
+++ b/src/resources/WebhookEndpoints.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../StripeResource');
+const {StripeResource} = require('../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/stripe.common.ts b/src/stripe.common.ts
index 968311a4..c81e01d9 100644
--- a/src/stripe.common.ts
+++ b/src/stripe.common.ts
@@ -1,6 +1,16 @@
-import _Error = require('./Error');
-
-import resources = require('./resources');
+import * as _Error from './Error';
+import {HttpClient, HttpClientResponse} from './net/HttpClient';
+import {
+  determineProcessUserAgentProperties,
+  pascalToCamelCase,
+  validateInteger,
+} from './utils';
+import {CryptoProvider} from './crypto/CryptoProvider';
+import {PlatformFunctions} from './platform/PlatformFunctions';
+import {RequestSender} from './RequestSender';
+import {StripeResource} from './StripeResource';
+import {createWebhooks} from './Webhooks';
+const resources = require('./resources');
 
 const DEFAULT_HOST = 'api.stripe.com';
 const DEFAULT_PORT = '443';
@@ -9,9 +19,6 @@ const DEFAULT_API_VERSION = (null as unknown) as string;
 
 const DEFAULT_TIMEOUT = 80000;
 
-import utils = require('./utils');
-const {determineProcessUserAgentProperties} = utils;
-
 const MAX_NETWORK_RETRY_DELAY_SEC = 2;
 const INITIAL_NETWORK_RETRY_DELAY_SEC = 0.5;
 
@@ -31,19 +38,12 @@ const ALLOWED_CONFIG_PROPERTIES = [
   'stripeAccount',
 ];
 
-import StripeResource = require('./StripeResource');
-import RequestSender = require('./RequestSender');
-import HttpClient = require('./net/HttpClient');
-import CryptoProvider = require('./crypto/CryptoProvider');
-import PlatformFunctions = require('./platform/PlatformFunctions');
-import createWebhooks = require('./Webhooks');
-
 type RequestSenderFactory = (stripe: StripeObject) => RequestSender;
 
 const defaultRequestSenderFactory: RequestSenderFactory = (stripe) =>
   new RequestSender(stripe, StripeResource.MAX_BUFFERED_REQUEST_METRICS);
 
-function createStripe(
+export function createStripe(
   platformFunctions: PlatformFunctions,
   requestSender: RequestSenderFactory = defaultRequestSenderFactory
 ): typeof Stripe {
@@ -58,8 +58,8 @@ function createStripe(
   };
   Stripe.StripeResource = StripeResource;
   Stripe.resources = resources;
-  Stripe.HttpClient = HttpClient.HttpClient;
-  Stripe.HttpClientResponse = HttpClient.HttpClientResponse;
+  Stripe.HttpClient = HttpClient;
+  Stripe.HttpClientResponse = HttpClientResponse;
   Stripe.CryptoProvider = CryptoProvider;
 
   function Stripe(
@@ -107,8 +107,8 @@ function createStripe(
       protocol: props.protocol || 'https',
       basePath: DEFAULT_BASE_PATH,
       version: props.apiVersion || DEFAULT_API_VERSION,
-      timeout: utils.validateInteger('timeout', props.timeout, DEFAULT_TIMEOUT),
-      maxNetworkRetries: utils.validateInteger(
+      timeout: validateInteger('timeout', props.timeout, DEFAULT_TIMEOUT),
+      maxNetworkRetries: validateInteger(
         'maxNetworkRetries',
         props.maxNetworkRetries,
         0
@@ -153,7 +153,7 @@ function createStripe(
   }
 
   Stripe.errors = _Error;
-  Stripe.webhooks = require('./Webhooks');
+  Stripe.webhooks = createWebhooks;
 
   Stripe.createNodeHttpClient = platformFunctions.createNodeHttpClient;
 
@@ -311,7 +311,7 @@ function createStripe(
       n: number,
       defaultVal?: number
     ): void {
-      const val = utils.validateInteger(prop, n, defaultVal);
+      const val = validateInteger(prop, n, defaultVal);
 
       this._setApiField(prop, val);
     },
@@ -410,7 +410,7 @@ function createStripe(
     _prepResources(): void {
       for (const name in resources) {
         // @ts-ignore
-        this[utils.pascalToCamelCase(name)] = new resources[name](this);
+        this[pascalToCamelCase(name)] = new resources[name](this);
       }
     },
 
@@ -458,5 +458,3 @@ function createStripe(
 
   return Stripe;
 }
-
-export = {createStripe};
diff --git a/src/stripe.node.ts b/src/stripe.node.ts
index 86268eb5..58ee373f 100644
--- a/src/stripe.node.ts
+++ b/src/stripe.node.ts
@@ -1,7 +1,7 @@
-import _Stripe = require('./stripe.common');
-import NodePlatformFunctions = require('./platform/NodePlatformFunctions');
+import {NodePlatformFunctions} from './platform/NodePlatformFunctions';
+import {createStripe} from './stripe.common';
 
-const Stripe = _Stripe.createStripe(new NodePlatformFunctions());
+const Stripe = createStripe(new NodePlatformFunctions());
 
 module.exports = Stripe;
 
diff --git a/src/stripe.worker.ts b/src/stripe.worker.ts
index 40aa7592..6012aecc 100644
--- a/src/stripe.worker.ts
+++ b/src/stripe.worker.ts
@@ -1,7 +1,7 @@
-import _Stripe = require('./stripe.common');
-import WebPlatformFunctions = require('./platform/WebPlatformFunctions');
+import {WebPlatformFunctions} from './platform/WebPlatformFunctions';
+import {createStripe} from './stripe.common';
 
-const Stripe = _Stripe.createStripe(new WebPlatformFunctions());
+const Stripe = createStripe(new WebPlatformFunctions());
 
 module.exports = Stripe;
 
diff --git a/src/utils.ts b/src/utils.ts
index 3c3583ff..85cf1fa8 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -23,344 +23,262 @@ type Options = {
   headers: Record<string, unknown>;
 };
 
-const utils = {
-  isOptionsHash(o: unknown): boolean | unknown {
-    return (
-      o &&
-      typeof o === 'object' &&
-      OPTIONS_KEYS.some((prop) => Object.prototype.hasOwnProperty.call(o, prop))
-    );
-  },
-
-  /**
-   * Stringifies an Object, accommodating nested objects
-   * (forming the conventional key 'parent[child]=value')
-   */
-  stringifyRequestData: (data: RequestData | string): string => {
-    return (
-      qs
-        .stringify(data, {
-          serializeDate: (d: Date) => Math.floor(d.getTime() / 1000),
-        })
-        // 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, ']')
-    );
-  },
-
-  /**
-   * Outputs a new function with interpolated object property values.
-   * Use like so:
-   *   const fn = makeURLInterpolator('some/url/{param1}/{param2}');
-   *   fn({ param1: 123, param2: 456 }); // => 'some/url/123/456'
-   */
-  makeURLInterpolator: ((): ((s: string) => UrlInterpolator) => {
-    const rc = {
-      '\n': '\\n',
-      '"': '\\"',
-      '\u2028': '\\u2028',
-      '\u2029': '\\u2029',
-    } as Record<string, string>;
-    return (str: string): UrlInterpolator => {
-      const cleanString = str.replace(/["\n\r\u2028\u2029]/g, ($0) => rc[$0]);
-      return (outputs: Record<string, unknown>): string => {
-        return cleanString.replace(/\{([\s\S]+?)\}/g, ($0, $1) =>
-          // @ts-ignore
-          encodeURIComponent(outputs[$1] || '')
-        );
-      };
+// const utils = {
+export function isOptionsHash(o: unknown): boolean | unknown {
+  return (
+    o &&
+    typeof o === 'object' &&
+    OPTIONS_KEYS.some((prop) => Object.prototype.hasOwnProperty.call(o, prop))
+  );
+}
+
+/**
+ * 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),
+      })
+      // 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, ']')
+  );
+}
+
+/**
+ * Outputs a new function with interpolated object property values.
+ * Use like so:
+ *   const fn = makeURLInterpolator('some/url/{param1}/{param2}');
+ *   fn({ param1: 123, param2: 456 }); // => 'some/url/123/456'
+ */
+export const makeURLInterpolator = ((): ((s: string) => UrlInterpolator) => {
+  const rc = {
+    '\n': '\\n',
+    '"': '\\"',
+    '\u2028': '\\u2028',
+    '\u2029': '\\u2029',
+  } as Record<string, string>;
+  return (str: string): UrlInterpolator => {
+    const cleanString = str.replace(/["\n\r\u2028\u2029]/g, ($0) => rc[$0]);
+    return (outputs: Record<string, unknown>): string => {
+      return cleanString.replace(/\{([\s\S]+?)\}/g, ($0, $1) =>
+        // @ts-ignore
+        encodeURIComponent(outputs[$1] || '')
+      );
     };
-  })(),
+  };
+})();
 
-  extractUrlParams: (path: string): Array<string> => {
-    const params = path.match(/\{\w+\}/g);
-    if (!params) {
-      return [];
-    }
+export function extractUrlParams(path: string): Array<string> {
+  const params = path.match(/\{\w+\}/g);
+  if (!params) {
+    return [];
+  }
 
-    return params.map((param) => param.replace(/[{}]/g, ''));
-  },
-
-  /**
-   * Return the data argument from a list of arguments
-   *
-   * @param {object[]} args
-   * @returns {object}
-   */
-  getDataFromArgs(args: RequestArgs): RequestData {
-    if (!Array.isArray(args) || !args[0] || typeof args[0] !== 'object') {
-      return {};
-    }
+  return params.map((param) => param.replace(/[{}]/g, ''));
+}
 
-    if (!utils.isOptionsHash(args[0])) {
-      return args.shift();
-    }
+/**
+ * Return the data argument from a list of arguments
+ *
+ * @param {object[]} args
+ * @returns {object}
+ */
+export function getDataFromArgs(args: RequestArgs): RequestData {
+  if (!Array.isArray(args) || !args[0] || typeof args[0] !== 'object') {
+    return {};
+  }
 
-    const argKeys = Object.keys(args[0]);
+  if (!isOptionsHash(args[0])) {
+    return args.shift();
+  }
 
-    const optionKeysInArgs = argKeys.filter((key) =>
-      OPTIONS_KEYS.includes(key)
+  const argKeys = Object.keys(args[0]);
+
+  const optionKeysInArgs = argKeys.filter((key) => OPTIONS_KEYS.includes(key));
+
+  // In some cases options may be the provided as the first argument.
+  // Here we're detecting a case where there are two distinct arguments
+  // (the first being args and the second options) and with known
+  // option keys in the first so that we can warn the user about it.
+  if (
+    optionKeysInArgs.length > 0 &&
+    optionKeysInArgs.length !== argKeys.length
+  ) {
+    emitWarning(
+      `Options found in arguments (${optionKeysInArgs.join(
+        ', '
+      )}). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.`
     );
+  }
 
-    // In some cases options may be the provided as the first argument.
-    // Here we're detecting a case where there are two distinct arguments
-    // (the first being args and the second options) and with known
-    // option keys in the first so that we can warn the user about it.
-    if (
-      optionKeysInArgs.length > 0 &&
-      optionKeysInArgs.length !== argKeys.length
-    ) {
-      emitWarning(
-        `Options found in arguments (${optionKeysInArgs.join(
-          ', '
-        )}). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.`
+  return {};
+}
+
+/**
+ * Return the options hash from a list of arguments
+ */
+export function getOptionsFromArgs(args: RequestArgs): Options {
+  const opts: Options = {
+    auth: null,
+    host: null,
+    headers: {},
+    settings: {},
+  };
+  if (args.length > 0) {
+    const arg = args[args.length - 1];
+    if (typeof arg === 'string') {
+      opts.auth = args.pop() as string;
+    } else if (isOptionsHash(arg)) {
+      const params = {...(args.pop() as Record<string, unknown>)};
+
+      const extraKeys = Object.keys(params).filter(
+        (key) => !OPTIONS_KEYS.includes(key)
       );
-    }
 
-    return {};
-  },
-
-  /**
-   * Return the options hash from a list of arguments
-   */
-  getOptionsFromArgs: (args: RequestArgs): Options => {
-    const opts: Options = {
-      auth: null,
-      host: null,
-      headers: {},
-      settings: {},
-    };
-    if (args.length > 0) {
-      const arg = args[args.length - 1];
-      if (typeof arg === 'string') {
-        opts.auth = args.pop() as string;
-      } else if (utils.isOptionsHash(arg)) {
-        const params = {...(args.pop() as Record<string, unknown>)};
-
-        const extraKeys = Object.keys(params).filter(
-          (key) => !OPTIONS_KEYS.includes(key)
+      if (extraKeys.length) {
+        emitWarning(
+          `Invalid options found (${extraKeys.join(', ')}); ignoring.`
         );
-
-        if (extraKeys.length) {
-          emitWarning(
-            `Invalid options found (${extraKeys.join(', ')}); ignoring.`
-          );
-        }
-
-        if (params.apiKey) {
-          opts.auth = params.apiKey as string;
-        }
-        if (params.idempotencyKey) {
-          opts.headers['Idempotency-Key'] = params.idempotencyKey;
-        }
-        if (params.stripeAccount) {
-          opts.headers['Stripe-Account'] = params.stripeAccount;
-        }
-        if (params.apiVersion) {
-          opts.headers['Stripe-Version'] = params.apiVersion;
-        }
-        if (Number.isInteger(params.maxNetworkRetries)) {
-          opts.settings.maxNetworkRetries = params.maxNetworkRetries as number;
-        }
-        if (Number.isInteger(params.timeout)) {
-          opts.settings.timeout = params.timeout as number;
-        }
-        if (params.host) {
-          opts.host = params.host as string;
-        }
       }
-    }
-    return opts;
-  },
-
-  /**
-   * Provide simple "Class" extension mechanism
-   */
-  protoExtend(this: any, sub: any): (...args: any[]) => void {
-    // eslint-disable-next-line @typescript-eslint/no-this-alias
-    const Super = this;
-    const Constructor = Object.prototype.hasOwnProperty.call(sub, 'constructor')
-      ? sub.constructor
-      : function(this: StripeResourceObject, ...args: any[]): void {
-          Super.apply(this, args);
-        };
-
-    // This initialization logic is somewhat sensitive to be compatible with
-    // divergent JS implementations like the one found in Qt. See here for more
-    // context:
-    //
-    // https://github.com/stripe/stripe-node/pull/334
-    Object.assign(Constructor, Super);
-    Constructor.prototype = Object.create(Super.prototype);
-    Object.assign(Constructor.prototype, sub);
-
-    return Constructor;
-  },
-
-  /**
-   * Remove empty values from an object
-   */
-  removeNullish: <T extends Record<string, unknown>>(obj: T): T => {
-    if (typeof obj !== 'object') {
-      throw new Error('Argument must be an object');
-    }
 
-    return Object.keys(obj).reduce<Record<string, unknown>>((result, key) => {
-      if (obj[key] != null) {
-        result[key] = obj[key];
+      if (params.apiKey) {
+        opts.auth = params.apiKey as string;
+      }
+      if (params.idempotencyKey) {
+        opts.headers['Idempotency-Key'] = params.idempotencyKey;
+      }
+      if (params.stripeAccount) {
+        opts.headers['Stripe-Account'] = params.stripeAccount;
+      }
+      if (params.apiVersion) {
+        opts.headers['Stripe-Version'] = params.apiVersion;
+      }
+      if (Number.isInteger(params.maxNetworkRetries)) {
+        opts.settings.maxNetworkRetries = params.maxNetworkRetries as number;
+      }
+      if (Number.isInteger(params.timeout)) {
+        opts.settings.timeout = params.timeout as number;
+      }
+      if (params.host) {
+        opts.host = params.host as string;
       }
-      return result;
-    }, {}) as T;
-  },
-
-  /**
-   * Normalize standard HTTP Headers:
-   * {'foo-bar': 'hi'}
-   * becomes
-   * {'Foo-Bar': 'hi'}
-   */
-  normalizeHeaders: (obj: RequestHeaders | null): RequestHeaders | null => {
-    if (!(obj && typeof obj === 'object')) {
-      return obj;
-    }
-
-    return Object.keys(obj).reduce<RequestHeaders>((result, header) => {
-      result[utils.normalizeHeader(header)] = obj[header];
-      return result;
-    }, {});
-  },
-
-  /**
-   * Stolen from https://github.com/marten-de-vries/header-case-normalizer/blob/master/index.js#L36-L41
-   * without the exceptions which are irrelevant to us.
-   */
-  normalizeHeader: (header: string): string => {
-    return header
-      .split('-')
-      .map(
-        (text) => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase()
-      )
-      .join('-');
-  },
-
-  callbackifyPromiseWithTimeout: <T>(
-    promise: Promise<T>,
-    callback: ((error: unknown, result: T | null) => void) | null
-  ): Promise<T | void> => {
-    if (callback) {
-      // Ensure callback is called outside of promise stack.
-      return promise.then(
-        (res) => {
-          setTimeout(() => {
-            callback(null, res);
-          }, 0);
-        },
-        (err) => {
-          setTimeout(() => {
-            callback(err, null);
-          }, 0);
-        }
-      );
     }
+  }
+  return opts;
+}
 
-    return promise;
-  },
-
-  /**
-   * Allow for special capitalization cases (such as OAuth)
-   */
-  pascalToCamelCase: (name: string): string => {
-    if (name === 'OAuth') {
-      return 'oauth';
-    } else {
-      return name[0].toLowerCase() + name.substring(1);
-    }
-  },
+/**
+ * Provide simple "Class" extension mechanism.
+ * <!-- Public API accessible via Stripe.StripeResource.extend -->
+ */
+export function protoExtend(this: any, sub: any): (...args: any[]) => void {
+  // eslint-disable-next-line @typescript-eslint/no-this-alias
+  const Super = this;
+  const Constructor = Object.prototype.hasOwnProperty.call(sub, 'constructor')
+    ? sub.constructor
+    : function(this: StripeResourceObject, ...args: any[]): void {
+        Super.apply(this, args);
+      };
 
-  emitWarning,
+  // This initialization logic is somewhat sensitive to be compatible with
+  // divergent JS implementations like the one found in Qt. See here for more
+  // context:
+  //
+  // https://github.com/stripe/stripe-node/pull/334
+  Object.assign(Constructor, Super);
+  Constructor.prototype = Object.create(Super.prototype);
+  Object.assign(Constructor.prototype, sub);
 
-  isObject: (obj: unknown): boolean => {
-    const type = typeof obj;
-    return (type === 'function' || type === 'object') && !!obj;
-  },
+  return Constructor;
+}
 
-  // For use in multipart requests
-  flattenAndStringify: (
-    data: MultipartRequestData
-  ): Record<string, string | Uint8Array> => {
-    const result: Record<string, string | Uint8Array> = {};
+/**
+ * Remove empty values from an object
+ */
+export function removeNullish<T extends Record<string, unknown>>(obj: T): T {
+  if (typeof obj !== 'object') {
+    throw new Error('Argument must be an object');
+  }
 
-    const step = (obj: MultipartRequestData, prevKey: string | null): void => {
-      Object.keys(obj).forEach((key) => {
-        // @ts-ignore
-        const value = obj[key];
-
-        const newKey = prevKey ? `${prevKey}[${key}]` : key;
-
-        if (utils.isObject(value)) {
-          if (
-            !(value instanceof Uint8Array) &&
-            !Object.prototype.hasOwnProperty.call(value, 'data')
-          ) {
-            // Non-buffer non-file Objects are recursively flattened
-            return step(value, newKey);
-          } else {
-            // Buffers and file objects are stored without modification
-            result[newKey] = value;
-          }
-        } else {
-          // Primitives are converted to strings
-          result[newKey] = String(value);
-        }
-      });
-    };
+  return Object.keys(obj).reduce<Record<string, unknown>>((result, key) => {
+    if (obj[key] != null) {
+      result[key] = obj[key];
+    }
+    return result;
+  }, {}) as T;
+}
 
-    step(data, null);
+/**
+ * Normalize standard HTTP Headers:
+ * {'foo-bar': 'hi'}
+ * becomes
+ * {'Foo-Bar': 'hi'}
+ */
+export function normalizeHeaders(
+  obj: RequestHeaders | null
+): RequestHeaders | null {
+  if (!(obj && typeof obj === 'object')) {
+    return obj;
+  }
 
+  return Object.keys(obj).reduce<RequestHeaders>((result, header) => {
+    result[normalizeHeader(header)] = obj[header];
     return result;
-  },
+  }, {});
+}
 
-  validateInteger: (name: string, n: unknown, defaultVal?: number): number => {
-    if (!Number.isInteger(n)) {
-      if (defaultVal !== undefined) {
-        return defaultVal;
-      } else {
-        throw new Error(`${name} must be an integer`);
+/**
+ * Stolen from https://github.com/marten-de-vries/header-case-normalizer/blob/master/index.js#L36-L41
+ * without the exceptions which are irrelevant to us.
+ */
+export function normalizeHeader(header: string): string {
+  return header
+    .split('-')
+    .map((text) => text.charAt(0).toUpperCase() + text.substr(1).toLowerCase())
+    .join('-');
+}
+
+export function callbackifyPromiseWithTimeout<T>(
+  promise: Promise<T>,
+  callback: ((error: unknown, result: T | null) => void) | null
+): Promise<T | void> {
+  if (callback) {
+    // Ensure callback is called outside of promise stack.
+    return promise.then(
+      (res) => {
+        setTimeout(() => {
+          callback(null, res);
+        }, 0);
+      },
+      (err) => {
+        setTimeout(() => {
+          callback(err, null);
+        }, 0);
       }
-    }
+    );
+  }
 
-    return n as number;
-  },
-
-  determineProcessUserAgentProperties: (): Record<string, string> => {
-    return typeof process === 'undefined'
-      ? {}
-      : {
-          lang_version: process.version,
-          platform: process.platform,
-        };
-  },
-
-  /**
-   * Joins an array of Uint8Arrays into a single Uint8Array
-   */
-  concat: (arrays: Array<Uint8Array>): Uint8Array => {
-    const totalLength = arrays.reduce((len, array) => len + array.length, 0);
-    const merged = new Uint8Array(totalLength);
-
-    let offset = 0;
-    arrays.forEach((array) => {
-      merged.set(array, offset);
-      offset += array.length;
-    });
+  return promise;
+}
 
-    return merged;
-  },
-};
+/**
+ * Allow for special capitalization cases (such as OAuth)
+ */
+export function pascalToCamelCase(name: string): string {
+  if (name === 'OAuth') {
+    return 'oauth';
+  } else {
+    return name[0].toLowerCase() + name.substring(1);
+  }
+}
 
-function emitWarning(warning: string): void {
+export function emitWarning(warning: string): void {
   if (typeof process.emitWarning !== 'function') {
     return console.warn(
       `Stripe: ${warning}`
@@ -370,4 +288,84 @@ function emitWarning(warning: string): void {
   return process.emitWarning(warning, 'Stripe');
 }
 
-export = utils;
+export function isObject(obj: unknown): boolean {
+  const type = typeof obj;
+  return (type === 'function' || type === 'object') && !!obj;
+}
+
+// For use in multipart requests
+export function flattenAndStringify(
+  data: MultipartRequestData
+): Record<string, string | Uint8Array> {
+  const result: Record<string, string | Uint8Array> = {};
+
+  const step = (obj: MultipartRequestData, prevKey: string | null): void => {
+    Object.keys(obj).forEach((key) => {
+      // @ts-ignore
+      const value = obj[key];
+
+      const newKey = prevKey ? `${prevKey}[${key}]` : key;
+
+      if (isObject(value)) {
+        if (
+          !(value instanceof Uint8Array) &&
+          !Object.prototype.hasOwnProperty.call(value, 'data')
+        ) {
+          // Non-buffer non-file Objects are recursively flattened
+          return step(value, newKey);
+        } else {
+          // Buffers and file objects are stored without modification
+          result[newKey] = value;
+        }
+      } else {
+        // Primitives are converted to strings
+        result[newKey] = String(value);
+      }
+    });
+  };
+
+  step(data, null);
+
+  return result;
+}
+
+export function validateInteger(
+  name: string,
+  n: unknown,
+  defaultVal?: number
+): number {
+  if (!Number.isInteger(n)) {
+    if (defaultVal !== undefined) {
+      return defaultVal;
+    } else {
+      throw new Error(`${name} must be an integer`);
+    }
+  }
+
+  return n as number;
+}
+
+export function determineProcessUserAgentProperties(): Record<string, string> {
+  return typeof process === 'undefined'
+    ? {}
+    : {
+        lang_version: process.version,
+        platform: process.platform,
+      };
+}
+
+/**
+ * Joins an array of Uint8Arrays into a single Uint8Array
+ */
+export function concat(arrays: Array<Uint8Array>): Uint8Array {
+  const totalLength = arrays.reduce((len, array) => len + array.length, 0);
+  const merged = new Uint8Array(totalLength);
+
+  let offset = 0;
+  arrays.forEach((array) => {
+    merged.set(array, offset);
+    offset += array.length;
+  });
+
+  return merged;
+}
diff --git a/tsconfig.json b/tsconfig.json
index 441cce93..d7d6eea4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,6 +10,7 @@
     "noImplicitThis": true,
     "strict": true,
     "strictFunctionTypes": true,
+    "types": [ "node" ]
   },
   "include": ["./src/**/*"]
 }
diff --git a/yarn.lock b/yarn.lock
index 08d65c4f..53fcbf96 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -364,6 +364,11 @@
   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"


Test patch:
diff --git a/lib/resources/TestHelpers/Customers.js b/lib/resources/TestHelpers/Customers.js
index 16044f0d..b4085559 100644
--- a/lib/resources/TestHelpers/Customers.js
+++ b/lib/resources/TestHelpers/Customers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     fundCashBalance: stripeMethod({
diff --git a/lib/resources/TestHelpers/Issuing/Cards.js b/lib/resources/TestHelpers/Issuing/Cards.js
index 6da5bca5..f8966a33 100644
--- a/lib/resources/TestHelpers/Issuing/Cards.js
+++ b/lib/resources/TestHelpers/Issuing/Cards.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     deliverCard: stripeMethod({
diff --git a/lib/resources/TestHelpers/Refunds.js b/lib/resources/TestHelpers/Refunds.js
index 79e16e8a..34a6198e 100644
--- a/lib/resources/TestHelpers/Refunds.js
+++ b/lib/resources/TestHelpers/Refunds.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     expire: stripeMethod({
diff --git a/lib/resources/TestHelpers/Terminal/Readers.js b/lib/resources/TestHelpers/Terminal/Readers.js
index 5db3ce22..1266b80e 100644
--- a/lib/resources/TestHelpers/Terminal/Readers.js
+++ b/lib/resources/TestHelpers/Terminal/Readers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     presentPaymentMethod: stripeMethod({
diff --git a/lib/resources/TestHelpers/TestClocks.js b/lib/resources/TestHelpers/TestClocks.js
index 0fe10bb8..d8ff65e7 100644
--- a/lib/resources/TestHelpers/TestClocks.js
+++ b/lib/resources/TestHelpers/TestClocks.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../StripeResource');
+const { StripeResource } = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/TestHelpers/Treasury/InboundTransfers.js b/lib/resources/TestHelpers/Treasury/InboundTransfers.js
index 8778a49a..51179230 100644
--- a/lib/resources/TestHelpers/Treasury/InboundTransfers.js
+++ b/lib/resources/TestHelpers/Treasury/InboundTransfers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     fail: stripeMethod({
diff --git a/lib/resources/TestHelpers/Treasury/OutboundPayments.js b/lib/resources/TestHelpers/Treasury/OutboundPayments.js
index b5f9d52b..2890d78f 100644
--- a/lib/resources/TestHelpers/Treasury/OutboundPayments.js
+++ b/lib/resources/TestHelpers/Treasury/OutboundPayments.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     fail: stripeMethod({
diff --git a/lib/resources/TestHelpers/Treasury/OutboundTransfers.js b/lib/resources/TestHelpers/Treasury/OutboundTransfers.js
index f10e448d..b52707a6 100644
--- a/lib/resources/TestHelpers/Treasury/OutboundTransfers.js
+++ b/lib/resources/TestHelpers/Treasury/OutboundTransfers.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     fail: stripeMethod({
diff --git a/lib/resources/TestHelpers/Treasury/ReceivedCredits.js b/lib/resources/TestHelpers/Treasury/ReceivedCredits.js
index 820e6118..937f549f 100644
--- a/lib/resources/TestHelpers/Treasury/ReceivedCredits.js
+++ b/lib/resources/TestHelpers/Treasury/ReceivedCredits.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/lib/resources/TestHelpers/Treasury/ReceivedDebits.js b/lib/resources/TestHelpers/Treasury/ReceivedDebits.js
index f6fbc7d5..a207d5ce 100644
--- a/lib/resources/TestHelpers/Treasury/ReceivedDebits.js
+++ b/lib/resources/TestHelpers/Treasury/ReceivedDebits.js
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec
 'use strict';
-const StripeResource = require('../../../StripeResource');
+const { StripeResource } = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 module.exports = StripeResource.extend({
     create: stripeMethod({
diff --git a/src/resources/TestHelpers/Customers.js b/src/resources/TestHelpers/Customers.js
index c0671f9b..b15192bd 100644
--- a/src/resources/TestHelpers/Customers.js
+++ b/src/resources/TestHelpers/Customers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Issuing/Cards.js b/src/resources/TestHelpers/Issuing/Cards.js
index a814ff65..47c74bd8 100644
--- a/src/resources/TestHelpers/Issuing/Cards.js
+++ b/src/resources/TestHelpers/Issuing/Cards.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Refunds.js b/src/resources/TestHelpers/Refunds.js
index 5302e652..a3069ddf 100644
--- a/src/resources/TestHelpers/Refunds.js
+++ b/src/resources/TestHelpers/Refunds.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Terminal/Readers.js b/src/resources/TestHelpers/Terminal/Readers.js
index f303abc1..35104548 100644
--- a/src/resources/TestHelpers/Terminal/Readers.js
+++ b/src/resources/TestHelpers/Terminal/Readers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/TestClocks.js b/src/resources/TestHelpers/TestClocks.js
index a0beacd3..6e466073 100644
--- a/src/resources/TestHelpers/TestClocks.js
+++ b/src/resources/TestHelpers/TestClocks.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../StripeResource');
+const {StripeResource} = require('../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Treasury/InboundTransfers.js b/src/resources/TestHelpers/Treasury/InboundTransfers.js
index e1a55c0b..d288456f 100644
--- a/src/resources/TestHelpers/Treasury/InboundTransfers.js
+++ b/src/resources/TestHelpers/Treasury/InboundTransfers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Treasury/OutboundPayments.js b/src/resources/TestHelpers/Treasury/OutboundPayments.js
index b7da93e6..53c41726 100644
--- a/src/resources/TestHelpers/Treasury/OutboundPayments.js
+++ b/src/resources/TestHelpers/Treasury/OutboundPayments.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Treasury/OutboundTransfers.js b/src/resources/TestHelpers/Treasury/OutboundTransfers.js
index 55b1a250..4e19d22b 100644
--- a/src/resources/TestHelpers/Treasury/OutboundTransfers.js
+++ b/src/resources/TestHelpers/Treasury/OutboundTransfers.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Treasury/ReceivedCredits.js b/src/resources/TestHelpers/Treasury/ReceivedCredits.js
index 53614059..87df0049 100644
--- a/src/resources/TestHelpers/Treasury/ReceivedCredits.js
+++ b/src/resources/TestHelpers/Treasury/ReceivedCredits.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/src/resources/TestHelpers/Treasury/ReceivedDebits.js b/src/resources/TestHelpers/Treasury/ReceivedDebits.js
index e19cf155..0314a577 100644
--- a/src/resources/TestHelpers/Treasury/ReceivedDebits.js
+++ b/src/resources/TestHelpers/Treasury/ReceivedDebits.js
@@ -2,7 +2,7 @@
 
 'use strict';
 
-const StripeResource = require('../../../StripeResource');
+const {StripeResource} = require('../../../StripeResource');
 const stripeMethod = StripeResource.method;
 
 module.exports = StripeResource.extend({
diff --git a/test/Error.spec.ts b/test/Error.spec.ts
index 91c251c9..19e72497 100644
--- a/test/Error.spec.ts
+++ b/test/Error.spec.ts
@@ -2,7 +2,7 @@
 
 require('../testUtils');
 
-import Error = require('../src/Error');
+import * as Error from '../src/Error';
 import {expect} from 'chai';
 
 describe('Error', () => {
diff --git a/test/PlatformFunctions.spec.ts b/test/PlatformFunctions.spec.ts
index fde5537d..1b5441c5 100644
--- a/test/PlatformFunctions.spec.ts
+++ b/test/PlatformFunctions.spec.ts
@@ -2,40 +2,35 @@
 
 require('../testUtils');
 
-import fs = require('fs');
-import path = require('path');
-import NodePlatformFunctions = require('../lib/platform/NodePlatformFunctions');
-import PlatformFunctions = require('../lib/platform/PlatformFunctions');
-import NodeCryptoProvider = require('../lib/crypto/NodeCryptoProvider');
-import SubtleCryptoProvider = require('../lib/crypto/SubtleCryptoProvider');
+import * as fs from 'fs';
+import * as path from 'path';
 
 import {FetchHttpClient} from '../lib/net/FetchHttpClient';
+import {NodeCryptoProvider} from '../lib/crypto/NodeCryptoProvider';
 import {NodeHttpClient} from '../lib/net/NodeHttpClient';
+import {NodePlatformFunctions} from '../lib/platform/NodePlatformFunctions';
+import {PlatformFunctions} from '../lib/platform/PlatformFunctions';
+import {SubtleCryptoProvider} from '../lib/crypto/SubtleCryptoProvider';
+
 import {expect} from 'chai';
 import {webcrypto} from 'crypto';
 
-let platforms: Record<string, PlatformFunctions>;
-
 if (process.versions.node < '15') {
   console.log(
     `Skipping WebPlatformFunctions tests. Cannot load WebPlatformFunctions because 'Event' is not available in the global scope for ${process.version}.`
   );
-  platforms = {
-    Node: new NodePlatformFunctions(),
-  };
 } else {
-  const WebPlatformFunctions = require('../lib/platform/WebPlatformFunctions');
-  platforms = {
-    Web: new WebPlatformFunctions(),
-    Node: new NodePlatformFunctions(),
-  };
+  import(
+    '../lib/platform/WebPlatformFunctions'
+  ).then(({WebPlatformFunctions}) => testPlatform(new WebPlatformFunctions()));
 }
 
-for (const platform in platforms) {
-  const platformFunctions = platforms[platform];
-  const isNodeEnvironment = platform === 'Node';
+testPlatform(new NodePlatformFunctions());
+
+function testPlatform(platformFunctions: PlatformFunctions): void {
+  const isNodeEnvironment = platformFunctions instanceof NodePlatformFunctions;
 
-  describe(`${platform}PlatformFunctions`, () => {
+  describe(`${platformFunctions.constructor.name}`, () => {
     describe('uuid', () => {
       describe('should use crypto.randomUUID if it exists', () => {
         const crypto = require('crypto');
diff --git a/test/RequestSender.spec.js b/test/RequestSender.spec.js
index a5be2a3b..6105474c 100644
--- a/test/RequestSender.spec.js
+++ b/test/RequestSender.spec.js
@@ -1,9 +1,10 @@
 'use strict';
 
+const {RequestSender} = require('../lib/RequestSender');
+
 const stripe = require('../testUtils').getSpyableStripe();
 const expect = require('chai').expect;
 
-const RequestSender = require('../lib/RequestSender');
 const {HttpClientResponse} = require('../lib/net/HttpClient');
 const utils = require('../testUtils');
 const nock = require('nock');
diff --git a/test/StripeResource.spec.js b/test/StripeResource.spec.js
index 793e9706..8b2b3aaa 100644
--- a/test/StripeResource.spec.js
+++ b/test/StripeResource.spec.js
@@ -6,7 +6,7 @@ const stripe = require('../testUtils').getSpyableStripe();
 const expect = require('chai').expect;
 const testUtils = require('../testUtils');
 
-const StripeResource = require('../lib/StripeResource');
+const {StripeResource} = require('../lib/StripeResource');
 const stripeMethod = StripeResource.method;
 
 describe('StripeResource', () => {
diff --git a/test/autoPagination.spec.js b/test/autoPagination.spec.js
index fc65b170..9205039c 100644
--- a/test/autoPagination.spec.js
+++ b/test/autoPagination.spec.js
@@ -3,10 +3,9 @@
 /* eslint-disable callback-return */
 
 const testUtils = require('../testUtils');
-const StripeResource = require('../lib/StripeResource');
+const {StripeResource} = require('../lib/StripeResource');
 
-const makeAutoPaginationMethods = require('../lib/autoPagination')
-  .makeAutoPaginationMethods;
+const {makeAutoPaginationMethods} = require('../lib/autoPagination');
 
 const expect = require('chai').expect;
 
diff --git a/test/crypto/NodeCryptoProvider.spec.js b/test/crypto/NodeCryptoProvider.spec.js
index 5b3e1f49..ac19f8de 100644
--- a/test/crypto/NodeCryptoProvider.spec.js
+++ b/test/crypto/NodeCryptoProvider.spec.js
@@ -1,6 +1,6 @@
 'use strict';
 
-const NodeCryptoProvider = require('../../lib/crypto/NodeCryptoProvider');
+const {NodeCryptoProvider} = require('../../lib/crypto/NodeCryptoProvider');
 
 const {createCryptoProviderTestSuite} = require('./helpers');
 
diff --git a/test/crypto/SubtleCryptoProvider.spec.js b/test/crypto/SubtleCryptoProvider.spec.js
index 2fc06717..7828c54e 100644
--- a/test/crypto/SubtleCryptoProvider.spec.js
+++ b/test/crypto/SubtleCryptoProvider.spec.js
@@ -1,6 +1,6 @@
 'use strict';
 
-const SubtleCryptoProvider = require('../../lib/crypto/SubtleCryptoProvider');
+const {SubtleCryptoProvider} = require('../../lib/crypto/SubtleCryptoProvider');
 const webcrypto = require('crypto').webcrypto;
 const expect = require('chai').expect;
 
diff --git a/test/utils.spec.ts b/test/utils.spec.ts
index 46ae8159..566cbbba 100644
--- a/test/utils.spec.ts
+++ b/test/utils.spec.ts
@@ -2,8 +2,8 @@
 
 require('../testUtils');
 
+import * as utils from '../lib/utils';
 import {expect} from 'chai';
-import utils = require('../lib/utils');
 
 describe('utils', () => {
   describe('makeURLInterpolator', () => {
diff --git a/testProjects/mjs/index.js b/testProjects/mjs/index.js
index 7489b17c..fd3bb046 100644
--- a/testProjects/mjs/index.js
+++ b/testProjects/mjs/index.js
@@ -1,9 +1,66 @@
 import {Stripe} from 'stripe';
 import DefaultStripe from 'stripe';
+import assert from 'assert';
+
+assert(Stripe.PACKAGE_VERSION);
+assert(Stripe.USER_AGENT);
+
+assert(Stripe.HttpClient);
+assert(Stripe.HttpClient.CONNECTION_CLOSED_ERROR_CODES);
+assert(Stripe.HttpClient.TIMEOUT_ERROR_CODE);
+assert(Stripe.HttpClient.makeTimeoutError);
+
+assert(Stripe.HttpClientResponse);
+assert(Stripe.createFetchHttpClient);
+assert(Stripe.createNodeHttpClient);
+
+assert(Stripe.CryptoProvider);
+assert(Stripe.createNodeCryptoProvider);
+assert(Stripe.createSubtleCryptoProvider);
+
+assert(Stripe.errors);
+assert(Stripe.errors.generate)
+assert(Stripe.errors.StripeError);
+assert(Stripe.errors.StripeCardError);
+assert(Stripe.errors.StripeInvalidRequestError);
+assert(Stripe.errors.StripeAPIError);
+assert(Stripe.errors.StripeAuthenticationError);
+assert(Stripe.errors.StripePermissionError);
+assert(Stripe.errors.StripeRateLimitError);
+assert(Stripe.errors.StripeConnectionError);
+assert(Stripe.errors.StripeSignatureVerificationError);
+assert(Stripe.errors.StripeIdempotencyError);
+assert(Stripe.errors.StripeInvalidGrantError);
+assert(Stripe.errors.StripeUnknownError);
+
+assert(Stripe.StripeResource);
+assert(Stripe.StripeResource.method);
+assert(Stripe.StripeResource.extend);
+assert(Stripe.StripeResource.MAX_BUFFERED_REQUEST_METRICS);
+
+assert(Stripe.webhooks);
+assert(Stripe.resources);
+
+assert(Stripe.Stripe);
+assert(Stripe.default);
 
 const stripe = new Stripe(process.argv[2]);
 const defaultStripe = new DefaultStripe(process.argv[2]);
 
+assert(stripe._platformFunctions);
+assert(stripe._api);
+assert(stripe._enableTelemetry);
+assert(stripe._prevRequestMetrics);
+assert(stripe._requestSender);
+assert(stripe.VERSION);
+assert(stripe.errors);
+assert(stripe.webhookEndpoints);
+assert(stripe.webhooks);
+assert(stripe._emitter);
+assert(stripe.on);
+assert(stripe.off);
+assert(stripe.once);
+
 try {
   throw new stripe.errors.StripeError({
     charge: 'foo',
diff --git a/testUtils/index.js b/testUtils/index.js
index cb6cf253..0965ed1e 100644
--- a/testUtils/index.js
+++ b/testUtils/index.js
@@ -8,9 +8,11 @@ require('chai').use(require('chai-as-promised'));
 
 const http = require('http');
 
-const CryptoProvider = require('../lib/crypto/CryptoProvider');
-const NodePlatformFunctions = require('../lib/platform/NodePlatformFunctions');
-const RequestSender = require('../lib/RequestSender');
+const {CryptoProvider} = require('../lib/crypto/CryptoProvider');
+const {
+  NodePlatformFunctions,
+} = require('../lib/platform/NodePlatformFunctions');
+const {RequestSender} = require('../lib/RequestSender');
 const {createStripe} = require('../lib/stripe.common');
 const stripe = require('../lib/stripe.node');