Skip to content

Commit

Permalink
Add raw_request (#2185)
Browse files Browse the repository at this point in the history
  • Loading branch information
prathmesh-stripe authored Sep 25, 2024
1 parent dd48563 commit 6d3cef2
Show file tree
Hide file tree
Showing 8 changed files with 387 additions and 7 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,40 @@ const stripe = new Stripe('sk_test_...', {
});
```

### Custom requests

If you would like to send a request to an undocumented API (for example you are in a private beta), or if you prefer to bypass the method definitions in the library and specify your request details directly, you can use the `rawRequest` method on the StripeClient object.

```javascript
const client = new Stripe('sk_test_...');

client.rawRequest(
'POST',
'/v1/beta_endpoint',
{ param: 123 },
{ apiVersion: '2022-11-15; feature_beta=v3' }
)
.then((response) => /* handle response */ )
.catch((error) => console.error(error));
```

Or using ES modules and `async`/`await`:

```javascript
import Stripe from 'stripe';
const stripe = new Stripe('sk_test_...');

const response = await stripe.rawRequest(
'POST',
'/v1/beta_endpoint',
{ param: 123 },
{ apiVersion: '2022-11-15; feature_beta=v3' }
);

// handle response
```


## Support

New features and bug fixes are released on the latest major version of the `stripe` package. If you are on an older major version, we recommend that you upgrade to the latest in order to use the new features and bug fixes including those for security vulnerabilities. Older major versions of the package will continue to be available for use, but will not be receiving any updates.
Expand Down
79 changes: 78 additions & 1 deletion src/RequestSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
normalizeHeaders,
removeNullish,
stringifyRequestData,
getDataFromArgs,
getOptionsFromArgs,
} from './utils.js';
import {HttpClient, HttpClientResponseInterface} from './net/HttpClient.js';
import {
Expand All @@ -24,6 +26,8 @@ import {
RequestData,
RequestOptions,
RequestDataProcessor,
RequestOpts,
RequestArgs,
} from './Types.js';

export type HttpClientResponseError = {code: string};
Expand Down Expand Up @@ -422,11 +426,84 @@ export class RequestSender {
}
}

_rawRequest(
method: string,
path: string,
params?: RequestData,
options?: RequestOptions
): Promise<any> {
const requestPromise = new Promise<any>((resolve, reject) => {
let opts: RequestOpts;
try {
const requestMethod = method.toUpperCase();
if (
requestMethod !== 'POST' &&
params &&
Object.keys(params).length !== 0
) {
throw new Error(
'rawRequest only supports params on POST requests. Please pass null and add your parameters to path.'
);
}
const args: RequestArgs = [].slice.call([params, options]);

// Pull request data and options (headers, auth) from args.
const dataFromArgs = getDataFromArgs(args);
const data = Object.assign({}, dataFromArgs);
const calculatedOptions = getOptionsFromArgs(args);

const headers = calculatedOptions.headers;

opts = {
requestMethod,
requestPath: path,
bodyData: data,
queryData: {},
auth: calculatedOptions.auth,
headers,
host: null,
streaming: false,
settings: {},
usage: ['raw_request'],
};
} catch (err) {
reject(err);
return;
}

function requestCallback(
err: any,
response: HttpClientResponseInterface
): void {
if (err) {
reject(err);
} else {
resolve(response);
}
}

const {headers, settings} = opts;

this._request(
opts.requestMethod,
opts.host,
path,
opts.bodyData,
opts.auth,
{headers, settings, streaming: opts.streaming},
opts.usage,
requestCallback
);
});

return requestPromise;
}

_request(
method: string,
host: string | null,
path: string,
data: RequestData,
data: RequestData | null,
auth: string | null,
options: RequestOptions = {},
usage: Array<string> = [],
Expand Down
14 changes: 13 additions & 1 deletion src/Types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,20 @@ export type StripeObject = {
_getPropsFromConfig: (config: Record<string, unknown>) => UserProvidedConfig;
_clientId?: string;
_platformFunctions: PlatformFunctions;
rawRequest: (
method: string,
path: string,
data: RequestData,
options: RequestOptions
) => Promise<any>;
};
export type RequestSender = {
_rawRequest(
method: string,
path: string,
params?: RequestData,
options?: RequestOptions
): Promise<any>;
_request(
method: string,
host: string | null,
Expand Down Expand Up @@ -211,7 +223,7 @@ export type StripeResourceObject = {
};
export type RequestDataProcessor = (
method: string,
data: RequestData,
data: RequestData | null,
headers: RequestHeaders | undefined,
prepareAndMakeRequest: (error: Error | null, data: string) => void
) => void;
Expand Down
17 changes: 16 additions & 1 deletion src/stripe.core.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import * as _Error from './Error.js';
import {RequestSender} from './RequestSender.js';
import {StripeResource} from './StripeResource.js';
import {AppInfo, StripeObject, UserProvidedConfig} from './Types.js';
import {
AppInfo,
StripeObject,
RequestData,
RequestOptions,
UserProvidedConfig,
} from './Types.js';
import {WebhookObject, createWebhooks} from './Webhooks.js';
import * as apiVersion from './apiVersion.js';
import {CryptoProvider} from './crypto/CryptoProvider.js';
Expand Down Expand Up @@ -208,6 +214,15 @@ export function createStripe(
_requestSender: null!,
_platformFunctions: null!,

rawRequest(
method: string,
path: string,
params?: RequestData,
options?: RequestOptions
): Promise<any> {
return this._requestSender._rawRequest(method, path, params, options);
},

/**
* @private
*/
Expand Down
14 changes: 10 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const OPTIONS_KEYS = [
'maxNetworkRetries',
'timeout',
'host',
'additionalHeaders',
];

type Settings = {
Expand All @@ -28,7 +29,7 @@ type Options = {
host: string | null;
settings: Settings;
streaming?: boolean;
headers: Record<string, unknown>;
headers: RequestHeaders;
};

export function isOptionsHash(o: unknown): boolean | unknown {
Expand Down Expand Up @@ -158,13 +159,13 @@ export function getOptionsFromArgs(args: RequestArgs): Options {
opts.auth = params.apiKey as string;
}
if (params.idempotencyKey) {
opts.headers['Idempotency-Key'] = params.idempotencyKey;
opts.headers['Idempotency-Key'] = params.idempotencyKey as string;
}
if (params.stripeAccount) {
opts.headers['Stripe-Account'] = params.stripeAccount;
opts.headers['Stripe-Account'] = params.stripeAccount as string;
}
if (params.apiVersion) {
opts.headers['Stripe-Version'] = params.apiVersion;
opts.headers['Stripe-Version'] = params.apiVersion as string;
}
if (Number.isInteger(params.maxNetworkRetries)) {
opts.settings.maxNetworkRetries = params.maxNetworkRetries as number;
Expand All @@ -175,6 +176,11 @@ export function getOptionsFromArgs(args: RequestArgs): Options {
if (params.host) {
opts.host = params.host as string;
}
if (params.additionalHeaders) {
opts.headers = params.additionalHeaders as {
[headerName: string]: string;
};
}
}
}
return opts;
Expand Down
Loading

0 comments on commit 6d3cef2

Please sign in to comment.