builtwith-api 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -2
- package/package.json +6 -3
- package/src/index.js +69 -52
- package/src/index.test.js +90 -0
- package/src/utils.js +13 -15
package/README.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
`builtwith-api` is a utility wrapper for the BuiltWith API suite.
|
|
4
4
|
|
|
5
|
+
Install using
|
|
6
|
+
```
|
|
7
|
+
yarn install builtwith-api
|
|
8
|
+
|
|
9
|
+
or
|
|
10
|
+
|
|
11
|
+
npm install builtwith-api
|
|
12
|
+
```
|
|
13
|
+
|
|
5
14
|
## Features
|
|
6
15
|
|
|
7
16
|
Response Formats
|
|
@@ -25,7 +34,7 @@ ________________
|
|
|
25
34
|
## How To Use
|
|
26
35
|
|
|
27
36
|
```js
|
|
28
|
-
const
|
|
37
|
+
const BuiltWith = require('builtwith-api')
|
|
29
38
|
|
|
30
39
|
const builtwith = BuiltWith(process.env.YOUR_BUILTWITH_API_KEY, {
|
|
31
40
|
responseFormat: 'json' // 'json' 'xml' 'txt' (only for lists API)
|
|
@@ -61,7 +70,9 @@ await builtwith.lists(technology, {
|
|
|
61
70
|
|
|
62
71
|
await builtwith.relationships(url)
|
|
63
72
|
|
|
64
|
-
|
|
73
|
+
const urls = ['hotelscombined.com', 'builtwith.com']
|
|
74
|
+
// Multi-domain lookup. Will automatically be converted into URI encoded array (hotelscombined.com,builtwith.com).
|
|
75
|
+
await builtwith.keywords(urls)
|
|
65
76
|
|
|
66
77
|
await builtwith.trends(technology, {
|
|
67
78
|
// Totals will be the closest to this date - providing the ability to get historical totals
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "builtwith-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Wrapper for the BuiltWith API",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {},
|
|
@@ -14,11 +14,14 @@
|
|
|
14
14
|
"BuiltWith",
|
|
15
15
|
"apis"
|
|
16
16
|
],
|
|
17
|
+
"files": [
|
|
18
|
+
"src",
|
|
19
|
+
"src/utils"
|
|
20
|
+
],
|
|
17
21
|
"author": "Zach Caceres (@zachcaceres)",
|
|
18
22
|
"license": "MIT",
|
|
19
23
|
"dependencies": {
|
|
20
|
-
"lodash": "^4.17.15"
|
|
21
|
-
"node-fetch": "^2.6.0"
|
|
24
|
+
"lodash": "^4.17.15"
|
|
22
25
|
},
|
|
23
26
|
"devDependencies": {
|
|
24
27
|
"dotenv": "^8.2.0"
|
package/src/index.js
CHANGED
|
@@ -1,34 +1,44 @@
|
|
|
1
|
-
const _ = require(
|
|
2
|
-
|
|
3
|
-
const utils = require("./utils")
|
|
4
|
-
const { VALID_RESPONSE_TYPES } = require("./config")
|
|
1
|
+
const _ = require("lodash");
|
|
5
2
|
|
|
3
|
+
const utils = require("./utils");
|
|
4
|
+
const { VALID_RESPONSE_TYPES } = require("./config");
|
|
6
5
|
|
|
7
6
|
function BuiltWith(apiKey, moduleParams = {}) {
|
|
8
|
-
const responseFormat = _.get(moduleParams,
|
|
7
|
+
const responseFormat = _.get(moduleParams, "responseFormat", "json");
|
|
9
8
|
|
|
10
9
|
if (!Object.values(VALID_RESPONSE_TYPES).includes(responseFormat)) {
|
|
11
|
-
throw new Error(
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Invalid 'responseFormat'. Valid format are 'xml', 'txt', and 'json'. You input ${responseFormat}`,
|
|
12
|
+
);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
if (responseFormat === VALID_RESPONSE_TYPES.TXT) {
|
|
15
|
-
console.warn(
|
|
16
|
+
console.warn(
|
|
17
|
+
"TXT response format is only supported for the BuiltWith Lists API. See: https://api.builtwith.com/lists-api",
|
|
18
|
+
);
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
function constructBuiltWithURL(
|
|
19
22
|
apiName,
|
|
20
23
|
requestParams = {},
|
|
21
|
-
subdomain =
|
|
24
|
+
subdomain = "api",
|
|
22
25
|
) {
|
|
23
|
-
let bwURL = `https://${subdomain}.builtwith.com/${apiName}/api.${responseFormat}?KEY=${apiKey}
|
|
26
|
+
let bwURL = `https://${subdomain}.builtwith.com/${apiName}/api.${responseFormat}?KEY=${apiKey}`;
|
|
24
27
|
|
|
25
28
|
if (!_.isEmpty(requestParams)) {
|
|
26
|
-
bwURL += `&${utils.paramsObjToQueryString(requestParams)}
|
|
29
|
+
bwURL += `&${utils.paramsObjToQueryString(requestParams)}`;
|
|
27
30
|
}
|
|
28
31
|
|
|
29
|
-
return bwURL
|
|
32
|
+
return bwURL;
|
|
30
33
|
}
|
|
31
34
|
|
|
35
|
+
function checkUrlData(url, isMultiDomain = true) {
|
|
36
|
+
let isArray = Array.isArray(url);
|
|
37
|
+
if (isArray) {
|
|
38
|
+
if (!isMultiDomain) throw "API does not allow for multi-domain LOOKUP";
|
|
39
|
+
if (url.length > 16) throw "Domain LOOKUP size to big (16 max)";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
32
42
|
|
|
33
43
|
return {
|
|
34
44
|
/**
|
|
@@ -37,12 +47,14 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
37
47
|
* @see https://api.builtwith.com/free-api
|
|
38
48
|
* @param {String} url
|
|
39
49
|
*/
|
|
40
|
-
free: async function(url) {
|
|
50
|
+
free: async function (url) {
|
|
51
|
+
checkUrlData(url, false);
|
|
52
|
+
|
|
41
53
|
const bwURL = constructBuiltWithURL("free1", {
|
|
42
|
-
LOOKUP: url
|
|
54
|
+
LOOKUP: url,
|
|
43
55
|
});
|
|
44
56
|
|
|
45
|
-
const res = await utils.makeStandardRequest(bwURL, responseFormat)
|
|
57
|
+
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
46
58
|
return res;
|
|
47
59
|
},
|
|
48
60
|
|
|
@@ -50,27 +62,28 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
50
62
|
* Make a request to the BuiltWith Domain API
|
|
51
63
|
*
|
|
52
64
|
* @see https://api.builtwith.com/domain-api
|
|
53
|
-
* @param {
|
|
65
|
+
* @param {(string|string[])} url
|
|
54
66
|
* @param {Object} params
|
|
55
67
|
*/
|
|
56
|
-
domain: async function(url, params) {
|
|
68
|
+
domain: async function (url, params) {
|
|
69
|
+
checkUrlData(url);
|
|
57
70
|
const hideAll = _.get(params, "hideAll", false);
|
|
58
71
|
const noMetaData = _.get(params, "noMetaData", false);
|
|
59
72
|
const noAttributeData = _.get(params, "noAttributeData", false);
|
|
60
73
|
const hideDescriptionAndLinks = _.get(
|
|
61
74
|
params,
|
|
62
75
|
"hideDescriptionAndLinks",
|
|
63
|
-
false
|
|
76
|
+
false,
|
|
64
77
|
);
|
|
65
78
|
const onlyLiveTechnologies = _.get(params, "onlyLiveTechnologies", false);
|
|
66
79
|
|
|
67
|
-
const bwURL = constructBuiltWithURL("
|
|
80
|
+
const bwURL = constructBuiltWithURL("v15", {
|
|
68
81
|
LOOKUP: url,
|
|
69
82
|
HIDETEXT: hideAll,
|
|
70
83
|
HIDEDL: hideDescriptionAndLinks,
|
|
71
84
|
LIVEONLY: onlyLiveTechnologies,
|
|
72
85
|
NOMETA: noMetaData,
|
|
73
|
-
NOATTR: noAttributeData
|
|
86
|
+
NOATTR: noAttributeData,
|
|
74
87
|
});
|
|
75
88
|
|
|
76
89
|
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
@@ -85,7 +98,7 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
85
98
|
* @param {String} technology
|
|
86
99
|
* @param {Object} params
|
|
87
100
|
*/
|
|
88
|
-
lists: async function(technology, params) {
|
|
101
|
+
lists: async function (technology, params) {
|
|
89
102
|
const includeMetaData = _.get(params, "includeMetaData", false);
|
|
90
103
|
const offset = _.get(params, "offset");
|
|
91
104
|
const since = _.get(params, "since");
|
|
@@ -94,11 +107,11 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
94
107
|
TECH: technology,
|
|
95
108
|
META: includeMetaData,
|
|
96
109
|
OFFSET: offset,
|
|
97
|
-
SINCE: since
|
|
110
|
+
SINCE: since,
|
|
98
111
|
});
|
|
99
112
|
|
|
100
|
-
const res = await utils.makeBulletProofRequest(bwURL)
|
|
101
|
-
return res
|
|
113
|
+
const res = await utils.makeBulletProofRequest(bwURL);
|
|
114
|
+
return res;
|
|
102
115
|
},
|
|
103
116
|
|
|
104
117
|
/**
|
|
@@ -107,11 +120,12 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
107
120
|
* @note Relationships API may throw an error related to the maxJSONLength property for certain URLs. This is thrown in BuiltWith and cannot be handled here.
|
|
108
121
|
*
|
|
109
122
|
* @see https://api.builtwith.com/relationships-api
|
|
110
|
-
* @param {
|
|
123
|
+
* @param {(string|string[])} url
|
|
111
124
|
*/
|
|
112
|
-
relationships: async function(url) {
|
|
125
|
+
relationships: async function (url) {
|
|
126
|
+
checkUrlData(url);
|
|
113
127
|
const bwURL = constructBuiltWithURL("rv1", {
|
|
114
|
-
LOOKUP: url
|
|
128
|
+
LOOKUP: url,
|
|
115
129
|
});
|
|
116
130
|
|
|
117
131
|
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
@@ -123,14 +137,15 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
123
137
|
* Make a request to the BuiltWith Keywords API
|
|
124
138
|
*
|
|
125
139
|
* @see https://api.builtwith.com/keywords-api
|
|
126
|
-
* @param {
|
|
140
|
+
* @param {(string|string[])} url
|
|
127
141
|
*/
|
|
128
|
-
keywords: async function(url) {
|
|
142
|
+
keywords: async function (url) {
|
|
143
|
+
checkUrlData(url);
|
|
129
144
|
const bwURL = constructBuiltWithURL("kw2", {
|
|
130
|
-
LOOKUP: url
|
|
145
|
+
LOOKUP: url,
|
|
131
146
|
});
|
|
132
147
|
|
|
133
|
-
const res = await utils.makeStandardRequest(bwURL, responseFormat)
|
|
148
|
+
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
134
149
|
return res;
|
|
135
150
|
},
|
|
136
151
|
|
|
@@ -141,16 +156,16 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
141
156
|
* @param {String} technology
|
|
142
157
|
* @param {Object} params
|
|
143
158
|
*/
|
|
144
|
-
trends: async function(technology, params) {
|
|
159
|
+
trends: async function (technology, params) {
|
|
145
160
|
const date = _.get(params, "date");
|
|
146
161
|
|
|
147
162
|
const bwURL = constructBuiltWithURL("trends/v6", {
|
|
148
163
|
TECH: technology,
|
|
149
|
-
DATE: date
|
|
164
|
+
DATE: date,
|
|
150
165
|
});
|
|
151
166
|
|
|
152
167
|
const res = await utils.makeBulletProofRequest(bwURL);
|
|
153
|
-
return res
|
|
168
|
+
return res;
|
|
154
169
|
},
|
|
155
170
|
|
|
156
171
|
/**
|
|
@@ -160,7 +175,7 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
160
175
|
* @param {String} companyName
|
|
161
176
|
* @param {Object} params
|
|
162
177
|
*/
|
|
163
|
-
companyToUrl: async function(companyName, params) {
|
|
178
|
+
companyToUrl: async function (companyName, params) {
|
|
164
179
|
const tld = _.get(params, "tld");
|
|
165
180
|
const amount = _.get(params, "noMetaData");
|
|
166
181
|
|
|
@@ -169,12 +184,12 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
169
184
|
{
|
|
170
185
|
COMPANY: encodeURIComponent(companyName),
|
|
171
186
|
TLD: tld,
|
|
172
|
-
AMOUNT: amount
|
|
187
|
+
AMOUNT: amount,
|
|
173
188
|
},
|
|
174
|
-
"ctu"
|
|
189
|
+
"ctu",
|
|
175
190
|
);
|
|
176
191
|
|
|
177
|
-
const res = await utils.makeStandardRequest(bwURL, responseFormat)
|
|
192
|
+
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
178
193
|
return res;
|
|
179
194
|
},
|
|
180
195
|
|
|
@@ -184,12 +199,12 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
184
199
|
* @see https://api.builtwith.com/domain-live-api
|
|
185
200
|
* @param {String} url
|
|
186
201
|
*/
|
|
187
|
-
domainLive: async function(url) {
|
|
188
|
-
const bwURL = constructBuiltWithURL("
|
|
189
|
-
LOOKUP: url
|
|
202
|
+
domainLive: async function (url) {
|
|
203
|
+
const bwURL = constructBuiltWithURL("ddlv2", {
|
|
204
|
+
LOOKUP: url,
|
|
190
205
|
});
|
|
191
206
|
|
|
192
|
-
const res = await utils.makeStandardRequest(bwURL, responseFormat)
|
|
207
|
+
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
193
208
|
return res;
|
|
194
209
|
},
|
|
195
210
|
|
|
@@ -200,28 +215,30 @@ function BuiltWith(apiKey, moduleParams = {}) {
|
|
|
200
215
|
* @param {String} url
|
|
201
216
|
* @param {Object} params
|
|
202
217
|
*/
|
|
203
|
-
trust: async function(url, params) {
|
|
204
|
-
const words = _.get(params, "words", "")
|
|
205
|
-
const live = _.get(params, "live", false)
|
|
218
|
+
trust: async function (url, params) {
|
|
219
|
+
const words = _.get(params, "words", "");
|
|
220
|
+
const live = _.get(params, "live", false);
|
|
206
221
|
|
|
207
222
|
const bwURL = constructBuiltWithURL("trustv1", {
|
|
208
223
|
LOOKUP: url,
|
|
209
224
|
// 'wordOne, wordTwo' ==> 'wordOne,wordTwo'
|
|
210
|
-
WORDS: words
|
|
211
|
-
|
|
225
|
+
WORDS: words
|
|
226
|
+
.split(",")
|
|
227
|
+
.map((wrd) => wrd.trim())
|
|
228
|
+
.join(","),
|
|
229
|
+
LIVE: live,
|
|
212
230
|
});
|
|
213
231
|
|
|
214
|
-
const res = await utils.makeStandardRequest(bwURL, responseFormat)
|
|
232
|
+
const res = await utils.makeStandardRequest(bwURL, responseFormat);
|
|
215
233
|
return res;
|
|
216
234
|
},
|
|
217
|
-
|
|
218
235
|
};
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
// Constructor to authenticate and get module
|
|
222
|
-
module.exports = function(apiKey, moduleParams) {
|
|
239
|
+
module.exports = function (apiKey, moduleParams) {
|
|
223
240
|
if (!apiKey) {
|
|
224
|
-
throw new Error(
|
|
241
|
+
throw new Error("You must initialize the BuiltWith module with an api key");
|
|
225
242
|
}
|
|
226
|
-
return BuiltWith(apiKey, moduleParams)
|
|
227
|
-
}
|
|
243
|
+
return BuiltWith(apiKey, moduleParams);
|
|
244
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const nock = require('nock');
|
|
2
|
+
const BuiltWith = require('../src/index');
|
|
3
|
+
|
|
4
|
+
const apiKey = 'testApiKey';
|
|
5
|
+
const moduleParams = { isBulletProof: false };
|
|
6
|
+
|
|
7
|
+
describe('BuiltWith', () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
nock('https://api.builtwith.com')
|
|
10
|
+
.get(/.*/)
|
|
11
|
+
.reply(200, { test: 'data' });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
nock.cleanAll();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should make a standard request for the domain API', async () => {
|
|
19
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
20
|
+
|
|
21
|
+
const response = await bw.domain('testUrl');
|
|
22
|
+
|
|
23
|
+
expect(response).toEqual({ test: 'data' });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should make a standard request for the lists API', async () => {
|
|
27
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
28
|
+
|
|
29
|
+
const response = await bw.lists('testUrl');
|
|
30
|
+
|
|
31
|
+
expect(response).toEqual({ test: 'data' });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should make a standard request for the relationships API', async () => {
|
|
35
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
36
|
+
|
|
37
|
+
const response = await bw.relationships('testUrl');
|
|
38
|
+
|
|
39
|
+
expect(response).toEqual({ test: 'data' });
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
it('should make a standard request for the free API', async () => {
|
|
44
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
45
|
+
|
|
46
|
+
const response = await bw.free('testUrl');
|
|
47
|
+
|
|
48
|
+
expect(response).toEqual({ test: 'data' });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should make a standard request for the keywords API', async () => {
|
|
52
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
53
|
+
|
|
54
|
+
const response = await bw.keywords('testUrl');
|
|
55
|
+
|
|
56
|
+
expect(response).toEqual({ test: 'data' });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should make a standard request for the trends API', async () => {
|
|
60
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
61
|
+
|
|
62
|
+
const response = await bw.trends('testUrl');
|
|
63
|
+
|
|
64
|
+
expect(response).toEqual({ test: 'data' });
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should make a standard request for the companyToUrl API', async () => {
|
|
68
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
69
|
+
|
|
70
|
+
const response = await bw.companyToUrl('My Company');
|
|
71
|
+
|
|
72
|
+
expect(response).toEqual({ test: 'data' });
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should make a standard request for the domainLive API', async () => {
|
|
76
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
77
|
+
|
|
78
|
+
const response = await bw.domainLive('testUrl');
|
|
79
|
+
|
|
80
|
+
expect(response).toEqual({ test: 'data' });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should make a standard request for the trust API', async () => {
|
|
84
|
+
const bw = BuiltWith(apiKey, moduleParams);
|
|
85
|
+
|
|
86
|
+
const response = await bw.trust('testUrl');
|
|
87
|
+
|
|
88
|
+
expect(response).toEqual({ test: 'data' });
|
|
89
|
+
});
|
|
90
|
+
});
|
package/src/utils.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { VALID_RESPONSE_TYPES } = require("./config")
|
|
1
|
+
const { VALID_RESPONSE_TYPES } = require("./config");
|
|
3
2
|
|
|
4
3
|
module.exports = {
|
|
5
|
-
makeStandardRequest: async function(url, responseFormat) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
});
|
|
4
|
+
makeStandardRequest: async function (url, responseFormat) {
|
|
5
|
+
const res = await fetch(url);
|
|
6
|
+
if (responseFormat === VALID_RESPONSE_TYPES.XML) {
|
|
7
|
+
return res.text();
|
|
8
|
+
} else {
|
|
9
|
+
return res.json();
|
|
10
|
+
}
|
|
13
11
|
},
|
|
14
12
|
|
|
15
|
-
makeBulletProofRequest: async function(url, responseFormat) {
|
|
13
|
+
makeBulletProofRequest: async function (url, responseFormat) {
|
|
16
14
|
const res = await fetch(url);
|
|
17
15
|
if (
|
|
18
16
|
responseFormat === VALID_RESPONSE_TYPES.TXT ||
|
|
@@ -29,7 +27,7 @@ module.exports = {
|
|
|
29
27
|
return JSON.parse(parsed);
|
|
30
28
|
} catch (e) {
|
|
31
29
|
console.warn(
|
|
32
|
-
"BuiltWith sent an invalid JSON payload. Falling back to text parsing."
|
|
30
|
+
"BuiltWith sent an invalid JSON payload. Falling back to text parsing.",
|
|
33
31
|
);
|
|
34
32
|
return parsed;
|
|
35
33
|
}
|
|
@@ -41,7 +39,7 @@ module.exports = {
|
|
|
41
39
|
* { paramOne: 'hello', paramTwo: 'goodbye' }
|
|
42
40
|
* @param {Object} params
|
|
43
41
|
*/
|
|
44
|
-
paramsObjToQueryString: function(params) {
|
|
42
|
+
paramsObjToQueryString: function (params) {
|
|
45
43
|
// '¶mOne=hello¶mTwo=goodbye
|
|
46
44
|
return Object.entries(params) // [['paramOne', 'hello'], ['paramTwo', 'goodbye]]
|
|
47
45
|
.filter(([, value]) => {
|
|
@@ -52,5 +50,5 @@ module.exports = {
|
|
|
52
50
|
return `${key}=${value}`; // ['paramOne=hello', 'paramTwo=goodbye']
|
|
53
51
|
})
|
|
54
52
|
.join("&"); // 'paramOne=hello¶mTwo=goodBye'
|
|
55
|
-
}
|
|
56
|
-
}
|
|
53
|
+
},
|
|
54
|
+
};
|