Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Stripe infrastructure to Typescript #1543

Merged
merged 3 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ module.exports = {
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/camelcase': 0,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/explicit-function-return-type': 0,
'prefer-rest-params': 'off',
Expand Down
92 changes: 65 additions & 27 deletions src/Error.js → src/Error.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,63 @@
'use strict';

type RawErrorType =
| 'card_error'
| 'invalid_request_error'
| 'api_error'
| 'idempotency_error'
| 'rate_limit_error'
| 'authentication_error'
| 'invalid_grant';

type StripeRawError = {
message?: string;
type?: RawErrorType;

headers?: {[header: string]: string};
statusCode?: number;
requestId?: string;
code?: string;
doc_url?: string;
decline_code?: string;
param?: string;
detail?: string;
charge?: string;
payment_method_type?: string;

payment_intent?: any;
payment_method?: any;
setup_intent?: any;
source?: any;
exception?: any;
};

/**
* 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 {
constructor(raw = {}) {
export class StripeError extends Error {
readonly message: string;
readonly type: string;
readonly raw: unknown;
readonly rawType: RawErrorType;
readonly headers: {[header: string]: string};
readonly requestId: string;

readonly code?: string;
readonly doc_url?: string;
readonly param?: string;
readonly detail?: string;
readonly statusCode?: number;
readonly charge?: string;
readonly decline_code?: string;
readonly payment_method_type?: string;

readonly payment_intent?: any;
readonly payment_method?: any;
readonly setup_intent?: any;
readonly source?: any;

constructor(raw: StripeRawError) {
super(raw.message);
this.type = this.constructor.name;

Expand Down Expand Up @@ -60,83 +112,69 @@ 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 {}
anniel-stripe marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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
* other named errors cover the problem. It could also be raised in the case
* 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 {}

/**
* 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
* expired, has been used, or doesn't belong to you; a refresh token doesn't
* 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 {}

module.exports.generate = StripeError.generate;
module.exports.StripeError = StripeError;
module.exports.StripeCardError = StripeCardError;
module.exports.StripeInvalidRequestError = StripeInvalidRequestError;
module.exports.StripeAPIError = StripeAPIError;
module.exports.StripeAuthenticationError = StripeAuthenticationError;
module.exports.StripePermissionError = StripePermissionError;
module.exports.StripeRateLimitError = StripeRateLimitError;
module.exports.StripeConnectionError = StripeConnectionError;
module.exports.StripeSignatureVerificationError = StripeSignatureVerificationError;
module.exports.StripeIdempotencyError = StripeIdempotencyError;
module.exports.StripeInvalidGrantError = StripeInvalidGrantError;
module.exports.StripeUnknownError = StripeUnknownError;
export class StripeUnknownError extends StripeError {}
9 changes: 4 additions & 5 deletions src/StripeMethod.js → src/StripeMethod.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict';

const utils = require('./utils');
const makeRequest = require('./makeRequest');
const makeAutoPaginationMethods = require('./autoPagination')
.makeAutoPaginationMethods;
import utils = require('./utils');
import makeRequest = require('./makeRequest');
import {makeAutoPaginationMethods} from './autoPagination';

/**
* Create an API method from the declared spec.
Expand Down Expand Up @@ -55,4 +54,4 @@ function stripeMethod(spec) {
};
}

module.exports = stripeMethod;
export = stripeMethod;
14 changes: 7 additions & 7 deletions src/StripeResource.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use strict';

const utils = require('./utils');
const {
StripeConnectionError,
import utils = require('./utils');
import {
StripeAPIError,
StripeAuthenticationError,
StripeConnectionError,
StripeError,
StripePermissionError,
StripeRateLimitError,
StripeError,
StripeAPIError,
} = require('./Error');
} from './Error';

const {HttpClient} = require('./net/HttpClient');
import {HttpClient} from './net/HttpClient';

type Settings = {
timeout?: number;
Expand Down
15 changes: 9 additions & 6 deletions src/autoPagination.js → src/autoPagination.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
'use strict';

const makeRequest = require('./makeRequest');
const utils = require('./utils');
import utils = require('./utils');
import makeRequest = require('./makeRequest');

function makeAutoPaginationMethods(self, requestArgs, spec, firstPagePromise) {
export function makeAutoPaginationMethods(
self,
requestArgs,
spec,
firstPagePromise
) {
const promiseCache = {currentPromise: null};
const reverseIteration = isReverseIteration(requestArgs);
let pagePromise = firstPagePromise;
Expand Down Expand Up @@ -94,8 +99,6 @@ function makeAutoPaginationMethods(self, requestArgs, spec, firstPagePromise) {
return autoPaginationMethods;
}

module.exports.makeAutoPaginationMethods = makeAutoPaginationMethods;

/**
* ----------------
* Private Helpers:
Expand Down Expand Up @@ -242,7 +245,7 @@ function makeAutoPagingToArray(autoPagingEach) {
}

function wrapAsyncIteratorWithCallback(asyncIteratorNext, onItem) {
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
function handleIteration(iterResult) {
if (iterResult.done) {
resolve();
Expand Down
4 changes: 2 additions & 2 deletions src/makeRequest.js → src/makeRequest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const utils = require('./utils');
import utils = require('./utils');

function getRequestOpts(self, requestArgs, spec, overrideData) {
// Extract spec values with defaults.
Expand Down Expand Up @@ -119,4 +119,4 @@ function makeRequest(self, requestArgs, spec, overrideData) {
});
}

module.exports = makeRequest;
export = makeRequest;
39 changes: 22 additions & 17 deletions src/stripe.js → src/stripe.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
'use strict';

const resources = require('./resources');
import resources = require('./resources');
import utils = require('./utils');

import {HttpClient, HttpClientResponse} from './net/HttpClient';
import {FetchHttpClient} from './net/FetchHttpClient';
import {NodeHttpClient} from './net/NodeHttpClient';

import CryptoProvider = require('./crypto/CryptoProvider');
import NodeCryptoProvider = require('./crypto/NodeCryptoProvider');
import SubtleCryptoProvider = require('./crypto/SubtleCryptoProvider');

const DEFAULT_HOST = 'api.stripe.com';
const DEFAULT_PORT = '443';
Expand All @@ -11,7 +20,6 @@ const DEFAULT_TIMEOUT = 80000;

Stripe.PACKAGE_VERSION = require('../package.json').version;

const utils = require('./utils');
const {determineProcessUserAgentProperties, emitWarning} = utils;

Stripe.USER_AGENT = {
Expand Down Expand Up @@ -50,16 +58,14 @@ const EventEmitter = require('events').EventEmitter;
Stripe.StripeResource = require('./StripeResource');
Stripe.resources = resources;

const {HttpClient, HttpClientResponse} = require('./net/HttpClient');
Stripe.HttpClient = HttpClient;
Stripe.HttpClientResponse = HttpClientResponse;

const CryptoProvider = require('./crypto/CryptoProvider');
Stripe.CryptoProvider = CryptoProvider;

function Stripe(key, config = {}) {
if (!(this instanceof Stripe)) {
return new Stripe(key, config);
return new (Stripe as any)(key, config);
}

const props = this._getPropsFromConfig(config);
Expand Down Expand Up @@ -138,7 +144,6 @@ Stripe.errors = require('./Error');
Stripe.webhooks = require('./Webhooks');

Stripe.createNodeHttpClient = (agent) => {
const {NodeHttpClient} = require('./net/NodeHttpClient');
return new NodeHttpClient(agent);
};

Expand All @@ -150,7 +155,6 @@ Stripe.createNodeHttpClient = (agent) => {
* passed, will default to the default `fetch` function in the global scope.
*/
Stripe.createFetchHttpClient = (fetchFn) => {
const {FetchHttpClient} = require('./net/FetchHttpClient');
return new FetchHttpClient(fetchFn);
};

Expand All @@ -159,7 +163,6 @@ Stripe.createFetchHttpClient = (fetchFn) => {
* its crypto operations.
*/
Stripe.createNodeCryptoProvider = () => {
const NodeCryptoProvider = require('./crypto/NodeCryptoProvider');
return new NodeCryptoProvider();
};

Expand All @@ -172,7 +175,6 @@ Stripe.createNodeCryptoProvider = () => {
* scope.
*/
Stripe.createSubtleCryptoProvider = (subtleCrypto) => {
const SubtleCryptoProvider = require('./crypto/SubtleCryptoProvider');
return new SubtleCryptoProvider(subtleCrypto);
};

Expand Down Expand Up @@ -326,15 +328,18 @@ Stripe.prototype = {

info = info || {};

const appInfo = APP_INFO_PROPERTIES.reduce((accum, prop) => {
if (typeof info[prop] == 'string') {
accum = accum || {};
const appInfo = APP_INFO_PROPERTIES.reduce(
(accum: Record<string, any>, prop) => {
if (typeof info[prop] == 'string') {
accum = accum || {};

accum[prop] = info[prop];
}
accum[prop] = info[prop];
}

return accum;
}, undefined);
return accum;
},
undefined
);

this._appInfo = appInfo;
},
Expand Down Expand Up @@ -483,7 +488,7 @@ Stripe.prototype = {
*/
getClientUserAgentSeeded(seed, cb) {
this.getUname((uname) => {
const userAgent = {};
const userAgent: any = {};
for (const field in seed) {
userAgent[field] = encodeURIComponent(seed[field]);
}
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"outDir": "./lib",
"allowJs": true,
"target": "es6",
"module": "commonjs",
"checkJs": false,
},
"include": ["./src/**/*"]
Expand Down