Skip to content

Commit cd4bb4c

Browse files
fix: axios targets not sending x-www-form-urlencoded properly (Kong#255)
Co-authored-by: Dimitri Mitropoulos <[email protected]>
1 parent f64080d commit cd4bb4c

24 files changed

Lines changed: 135 additions & 50 deletions

src/helpers/code-builder.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,25 @@ describe('codeBuilder', () => {
1818
expect(result).toBe(`${indent.repeat(2)}${line}`);
1919
});
2020
});
21+
22+
describe('addPostProcessor', () => {
23+
it('replaces accordingly with one replacer', () => {
24+
const indent = '\t';
25+
const { join, addPostProcessor, push } = new CodeBuilder({ indent });
26+
push('console.log("hello world")');
27+
addPostProcessor(code => code.replace(/console/, 'REPLACED'));
28+
29+
expect(join()).toBe('REPLACED.log("hello world")');
30+
});
31+
32+
it('replaces accordingly with multiple replacers', () => {
33+
const indent = '\t';
34+
const { join, addPostProcessor, push } = new CodeBuilder({ indent });
35+
push('console.log("hello world")');
36+
addPostProcessor(code => code.replace(/world/, 'nurse!!'));
37+
addPostProcessor(code => code.toUpperCase());
38+
39+
expect(join()).toBe('CONSOLE.LOG("HELLO NURSE!!")');
40+
});
41+
});
2142
});

src/helpers/code-builder.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const DEFAULT_INDENTATION_CHARACTER = '';
22
const DEFAULT_LINE_JOIN = '\n';
33

4+
export type PostProcessor = (unreplacedCode: string) => string;
5+
46
export interface CodeBuilderOptions {
57
/**
68
* Desired indentation character for aggregated lines of code
@@ -16,6 +18,7 @@ export interface CodeBuilderOptions {
1618
}
1719

1820
export class CodeBuilder {
21+
postProcessors: PostProcessor[] = [];
1922
code: string[] = [];
2023
indentationCharacter: string = DEFAULT_INDENTATION_CHARACTER;
2124
lineJoin = DEFAULT_LINE_JOIN;
@@ -61,7 +64,22 @@ export class CodeBuilder {
6164
};
6265

6366
/**
64-
* Concatenate all current lines using the given lineJoin
67+
* Concatenate all current lines using the given lineJoin, then apply any replacers that may have been added
68+
*/
69+
join = () => {
70+
const unreplacedCode = this.code.join(this.lineJoin);
71+
const replacedOutput = this.postProcessors.reduce(
72+
(accumulator, replacer) => replacer(accumulator),
73+
unreplacedCode,
74+
);
75+
return replacedOutput;
76+
};
77+
78+
/**
79+
* Often when writing modules you may wish to add a literal tag or bit of metadata that you wish to transform after other processing as a final step.
80+
* To do so, you can provide a PostProcessor function and it will be run automatically for you when you call `join()` later on.
6581
*/
66-
join = () => this.code.join(this.lineJoin);
82+
addPostProcessor = (postProcessor: PostProcessor) => {
83+
this.postProcessors = [...this.postProcessors, postProcessor];
84+
};
6785
}

src/targets/javascript/axios/client.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const axios: Client = {
2626
...options,
2727
};
2828

29-
const { blank, push, join } = new CodeBuilder({ indent: opts.indent });
29+
const { blank, push, join, addPostProcessor } = new CodeBuilder({ indent: opts.indent });
3030

3131
push("import axios from 'axios';");
3232
blank();
@@ -46,7 +46,18 @@ export const axios: Client = {
4646

4747
switch (postData.mimeType) {
4848
case 'application/x-www-form-urlencoded':
49-
requestOptions.data = postData.paramsObj;
49+
if (postData.params) {
50+
push('const encodedParams = new URLSearchParams();');
51+
postData.params.forEach(param => {
52+
push(`encodedParams.set('${param.name}', '${param.value}');`);
53+
});
54+
55+
blank();
56+
57+
requestOptions.data = 'encodedParams,';
58+
addPostProcessor(code => code.replace(/'encodedParams,'/, 'encodedParams,'));
59+
}
60+
5061
break;
5162

5263
case 'application/json':

src/targets/javascript/axios/fixtures/application-form-encoded.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import axios from 'axios';
22

3+
const encodedParams = new URLSearchParams();
4+
encodedParams.set('foo', 'bar');
5+
encodedParams.set('hello', 'world');
6+
37
const options = {
48
method: 'POST',
59
url: 'http://mockbin.com/har',
610
headers: {'content-type': 'application/x-www-form-urlencoded'},
7-
data: {foo: 'bar', hello: 'world'}
11+
data: encodedParams,
812
};
913

1014
axios

src/targets/javascript/axios/fixtures/full.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import axios from 'axios';
22

3+
const encodedParams = new URLSearchParams();
4+
encodedParams.set('foo', 'bar');
5+
36
const options = {
47
method: 'POST',
58
url: 'http://mockbin.com/har',
@@ -9,7 +12,7 @@ const options = {
912
accept: 'application/json',
1013
'content-type': 'application/x-www-form-urlencoded'
1114
},
12-
data: {foo: 'bar'}
15+
data: encodedParams,
1316
};
1417

1518
axios

src/targets/node/axios/client.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@ export const axios: Client = {
2525
indent: ' ',
2626
...options,
2727
};
28+
const { blank, join, push, addPostProcessor } = new CodeBuilder({ indent: opts.indent });
2829

29-
const { blank, join, push } = new CodeBuilder({ indent: opts.indent });
30-
31-
push("var axios = require('axios').default;");
32-
blank();
30+
push("const axios = require('axios').default;");
3331

3432
const reqOpts: Record<string, any> = {
3533
method,
@@ -46,23 +44,39 @@ export const axios: Client = {
4644

4745
switch (postData.mimeType) {
4846
case 'application/x-www-form-urlencoded':
49-
reqOpts.data = postData.paramsObj;
47+
if (postData.params) {
48+
push("const { URLSearchParams } = require('url');");
49+
blank();
50+
51+
push('const encodedParams = new URLSearchParams();');
52+
postData.params.forEach(param => {
53+
push(`encodedParams.set('${param.name}', '${param.value}');`);
54+
});
55+
56+
blank();
57+
58+
reqOpts.data = 'encodedParams,';
59+
addPostProcessor(code => code.replace(/'encodedParams,'/, 'encodedParams,'));
60+
}
61+
5062
break;
5163

5264
case 'application/json':
65+
blank();
5366
if (postData.jsonObj) {
5467
reqOpts.data = postData.jsonObj;
5568
}
5669
break;
5770

5871
default:
72+
blank();
5973
if (postData.text) {
6074
reqOpts.data = postData.text;
6175
}
6276
}
6377

6478
const stringifiedOptions = stringifyObject(reqOpts, { indent: ' ', inlineCharacterLimit: 80 });
65-
push(`var options = ${stringifiedOptions};`);
79+
push(`const options = ${stringifiedOptions};`);
6680
blank();
6781

6882
push('axios');

src/targets/node/axios/fixtures/application-form-encoded.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
var axios = require('axios').default;
1+
const axios = require('axios').default;
2+
const { URLSearchParams } = require('url');
23

3-
var options = {
4+
const encodedParams = new URLSearchParams();
5+
encodedParams.set('foo', 'bar');
6+
encodedParams.set('hello', 'world');
7+
8+
const options = {
49
method: 'POST',
510
url: 'http://mockbin.com/har',
611
headers: {'content-type': 'application/x-www-form-urlencoded'},
7-
data: {foo: 'bar', hello: 'world'}
12+
data: encodedParams,
813
};
914

1015
axios

src/targets/node/axios/fixtures/application-json.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
var axios = require('axios').default;
1+
const axios = require('axios').default;
22

3-
var options = {
3+
const options = {
44
method: 'POST',
55
url: 'http://mockbin.com/har',
66
headers: {'content-type': 'application/json'},

src/targets/node/axios/fixtures/cookies.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
var axios = require('axios').default;
1+
const axios = require('axios').default;
22

3-
var options = {
3+
const options = {
44
method: 'POST',
55
url: 'http://mockbin.com/har',
66
headers: {cookie: 'foo=bar; bar=baz'}

src/targets/node/axios/fixtures/custom-method.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
var axios = require('axios').default;
1+
const axios = require('axios').default;
22

3-
var options = {method: 'PROPFIND', url: 'http://mockbin.com/har'};
3+
const options = {method: 'PROPFIND', url: 'http://mockbin.com/har'};
44

55
axios
66
.request(options)

0 commit comments

Comments
 (0)