Skip to content

Commit

Permalink
Add support for fullPath on methods. (#1200)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcr-stripe committed Jul 28, 2021
1 parent f0f016f commit 604d2ec
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 5 deletions.
9 changes: 8 additions & 1 deletion lib/StripeMethod.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const makeAutoPaginationMethods = require('./autoPagination')
* @param [spec.method='GET'] Request Method (POST, GET, DELETE, PUT)
* @param [spec.path=''] Path to be appended to the API BASE_PATH, joined with
* the instance's path (e.g. 'charges' or 'customers')
* @param [spec.fullPath=''] Fully qualified path to the method (eg. /v1/a/b/c).
* If this is specified, path should not be specified.
* @param [spec.urlParams=[]] Array of required arguments in the order that they
* must be passed by the consumer of the API. Subsequent optional arguments are
* optionally passed through a hash (Object) as the penultimate argument
Expand All @@ -20,11 +22,16 @@ const makeAutoPaginationMethods = require('./autoPagination')
* @param [spec.host] Hostname for the request.
*/
function stripeMethod(spec) {
if (spec.path !== undefined && spec.fullPath !== undefined) {
throw new Error(
`Method spec specified both a 'path' (${spec.path}) and a 'fullPath' (${spec.fullPath}).`
);
}
return function(...args) {
const callback = typeof args[args.length - 1] == 'function' && args.pop();

spec.urlParams = utils.extractUrlParams(
this.createResourcePathWithSymbols(spec.path || '')
spec.fullPath || this.createResourcePathWithSymbols(spec.path || '')
);

const requestPromise = utils.callbackifyPromiseWithTimeout(
Expand Down
19 changes: 16 additions & 3 deletions lib/makeRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ const utils = require('./utils');

function getRequestOpts(self, requestArgs, spec, overrideData) {
// Extract spec values with defaults.
const commandPath = utils.makeURLInterpolator(spec.path || '');
const requestMethod = (spec.method || 'GET').toUpperCase();
const urlParams = spec.urlParams || [];
const encode = spec.encode || ((data) => data);
const path = self.createResourcePathWithSymbols(spec.path);

const isUsingFullPath = !!spec.fullPath;
const commandPath = utils.makeURLInterpolator(
isUsingFullPath ? spec.fullPath : spec.path || ''
);

// When using fullPath, we ignore the resource path as it should already be
// fully qualified.
const path = isUsingFullPath
? spec.fullPath
: self.createResourcePathWithSymbols(spec.path);

// Don't mutate args externally.
const args = [].slice.call(requestArgs);
Expand Down Expand Up @@ -39,7 +48,11 @@ function getRequestOpts(self, requestArgs, spec, overrideData) {
);
}

const requestPath = self.createFullPath(commandPath, urlData);
// When using full path, we can just invoke the URL interpolator directly
// as we don't need to use the resource to create a full path.
const requestPath = isUsingFullPath
? commandPath(urlData)
: self.createFullPath(commandPath, urlData);
const headers = Object.assign(options.headers, spec.headers);

if (spec.validator) {
Expand Down
32 changes: 32 additions & 0 deletions test/StripeResource.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,38 @@ describe('StripeResource', () => {
});
});

describe('method with fullPath', () => {
it('interpolates in parameters', (callback) => {
const handleRequest = (req, res) => {
expect(req.url).to.equal('/v1/parent/hello/child/world');

// Write back JSON to close out the server.
res.write('{}');
res.end();
};

testUtils.getTestServerStripe(
{},
handleRequest,
(err, stripe, closeServer) => {
const resource = new (StripeResource.extend({
test: stripeMethod({
method: 'GET',
fullPath: '/v1/parent/{param1}/child/{param2}',
}),
}))(stripe);

return resource.test('hello', 'world', (err, res) => {
closeServer();
// Spot check that we received a response.
expect(res).to.deep.equal({});
return callback(err);
});
}
);
});
});

describe('streaming', () => {
/**
* Defines a fake resource with a `pdf` method
Expand Down
39 changes: 39 additions & 0 deletions test/makeRequest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require('../testUtils');

const makeRequest = require('../lib/makeRequest');
const utils = require('../lib/utils');
const expect = require('chai').expect;

describe('makeRequest', () => {
Expand All @@ -26,4 +27,42 @@ describe('makeRequest', () => {
]);
});
});

describe('makeRequest with fullPath', () => {
it('handles urlData', async () => {
const args = ['hello', 'world'];

const fullPath = '/v1/parent/{param1}/child/{param2}';
const spec = {
fullPath,
urlParams: utils.extractUrlParams(fullPath),
};

let actualPath;
const mockSelf = {
// These two methods shouldn't be called when using a fullPath, as they
// don't rely on the resource path.
createResourcePathWithSymbols: () => {
throw new Error('Unexpected call to createResourcePathWithSymbols.');
},
createFullPath: () => {
throw new Error('Unexpected call to createFullPath.');
},
_request: (
_method,
_host,
path,
_body,
_auth,
_headers,
requestCallback
) => {
actualPath = path;
requestCallback(null, 'response');
},
};
await makeRequest(mockSelf, args, spec, {});
expect(actualPath).to.equal('/v1/parent/hello/child/world');
});
});
});
3 changes: 2 additions & 1 deletion types/lib.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ declare module 'stripe' {
>(spec: T): StripeResource & T;
static method(spec: {
method: string;
path: string;
path?: string;
fullPath?: string;
methodType?: 'list';
}): (...args: any[]) => object; //eslint-disable-line @typescript-eslint/no-explicit-any
static BASIC_METHODS: {
Expand Down
4 changes: 4 additions & 0 deletions types/test/typescriptTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ Stripe.StripeResource.extend({
method: 'create',
path: 'foo',
}),
fooFullPath: Stripe.StripeResource.method({
method: 'create',
fullPath: '/v1/full/path',
}),
});

const maxBufferedRequestMetrics: number =
Expand Down

0 comments on commit 604d2ec

Please sign in to comment.