UNPKG

3.82 kBJavaScriptView Raw
1const request = require('request');
2const requestPN = require('request-promise-native');
3const { version } = require('./package.json');
4const { getPortalConfig, getAndLoadConfigIfNeeded } = require('./lib/config');
5const { getOauthManager } = require('./oauth');
6
7const withOauth = async (portalId, portalConfig, requestOptions) => {
8 const { headers } = requestOptions;
9 const oauth = getOauthManager(portalId, portalConfig);
10 const accessToken = await oauth.accessToken();
11 return {
12 ...requestOptions,
13 headers: {
14 ...headers,
15 Authorization: `Bearer ${accessToken}`,
16 },
17 };
18};
19
20const getRequestOptions = (options = {}, requestOptions = {}) => {
21 const { env } = options;
22 const { httpTimeout, httpUseLocalhost } = getAndLoadConfigIfNeeded();
23 return {
24 baseUrl: `https://${httpUseLocalhost ? 'local' : 'api'}.hubapi${
25 env === 'QA' ? 'qa' : ''
26 }.com`,
27 headers: {
28 'User-Agent': `HubSpot CMS Tools/${version}`,
29 },
30 json: true,
31 simple: true,
32 timeout: httpTimeout || 15000,
33 ...requestOptions,
34 };
35};
36
37const withPortalId = (portalId, requestOptions) => {
38 const { qs } = requestOptions;
39
40 return {
41 ...requestOptions,
42 qs: {
43 ...qs,
44 portalId,
45 },
46 };
47};
48
49const withAuth = async (portalId, options) => {
50 const portalConfig = getPortalConfig(portalId);
51 const { env, authType, apiKey } = portalConfig;
52 const requestOptions = withPortalId(
53 portalId,
54 getRequestOptions({ env }, options)
55 );
56
57 if (authType === 'oauth2') {
58 return withOauth(portalId, portalConfig, requestOptions);
59 }
60 const { qs } = requestOptions;
61
62 return {
63 ...requestOptions,
64 qs: {
65 ...qs,
66 hapikey: apiKey,
67 },
68 };
69};
70
71const addQueryParams = (requestOptions, params = {}) => {
72 const { qs } = requestOptions;
73 return {
74 ...requestOptions,
75 qs: {
76 ...qs,
77 ...params,
78 },
79 };
80};
81
82const getRequest = async (portalId, options) => {
83 const { query, ...rest } = options;
84 const requestOptions = addQueryParams(rest, query);
85 return requestPN.get(await withAuth(portalId, requestOptions));
86};
87
88const postRequest = async (portalId, options) => {
89 return requestPN.post(await withAuth(portalId, options));
90};
91
92const putRequest = async (portalId, options) => {
93 return requestPN.put(await withAuth(portalId, options));
94};
95
96const deleteRequest = async (portalId, options) => {
97 return requestPN.del(await withAuth(portalId, options));
98};
99
100const createGetRequestStream = ({ contentType }) => async (
101 portalId,
102 options,
103 destination
104) => {
105 const { query, ...rest } = options;
106 const requestOptions = addQueryParams(rest, query);
107 // Using `request` instead of `request-promise` per the docs so
108 // the response can be piped.
109 // https://github.com/request/request-promise#api-in-detail
110 //
111 // eslint-disable-next-line no-async-promise-executor
112 return new Promise(async (resolve, reject) => {
113 try {
114 const { headers, ...opts } = await withAuth(portalId, requestOptions);
115 const req = request.get({
116 ...opts,
117 headers: {
118 ...headers,
119 'content-type': contentType,
120 accept: contentType,
121 },
122 json: false,
123 });
124 let response;
125 req
126 .on('error', reject)
127 .on('response', r => {
128 if (r.statusCode >= 200 && r.statusCode < 300) {
129 response = r;
130 } else {
131 reject(r);
132 }
133 })
134 .on('end', () => resolve(response))
135 .pipe(destination);
136 } catch (err) {
137 reject(err);
138 }
139 });
140};
141
142module.exports = {
143 getRequestOptions,
144 request: requestPN,
145 get: getRequest,
146 getOctetStream: createGetRequestStream({
147 contentType: 'application/octet-stream',
148 }),
149 post: postRequest,
150 put: putRequest,
151 delete: deleteRequest,
152};