Skip to content

Commit ba0f85c

Browse files
committed
merge main to demo
2 parents bc6063c + c14a088 commit ba0f85c

File tree

8 files changed

+647
-34
lines changed

8 files changed

+647
-34
lines changed

ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"lint:fix": "eslint --fix ."
1212
},
1313
"dependencies": {
14-
"@bany/curl-to-json": "^1.2.7",
1514
"@chakra-ui/icons": "^2.0.17",
1615
"@chakra-ui/react": "^2.4.9",
1716
"@clerk/clerk-react": "^4.17.0",
@@ -28,6 +27,7 @@
2827
"echarts-for-react": "^3.0.2",
2928
"framer-motion": "^9.0.2",
3029
"html-react-parser": "^3.0.16",
30+
"minimist": "^1.2.8",
3131
"query-string": "^8.1.0",
3232
"react": "^18.2.0",
3333
"react-animated-number": "^0.4.4",

ui/src/pages/Dashboard/AddEditRequest/selectedRequest.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ function ImportCurl() {
5959

6060
const importCurlCmd = async () => {
6161
try {
62+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
63+
// @ts-ignore
6264
const payload = convertToCurl(text);
6365
dispatch(curlToRequest(payload as CurlToJSONPayload));
6466
setOpen(false);

ui/src/utils/curlParser/convertor.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/* eslint-disable prefer-destructuring */
2+
/**
3+
* Parse header field.
4+
*/
5+
6+
function parseField(s) {
7+
return s.replace(/:(\s+)/, ":").split(/:(.+)/);
8+
}
9+
10+
function parseFieldWithEqual(s) {
11+
return s.split(/=(.+)/);
12+
}
13+
14+
function pareString(s, pareCallBack = parseField) {
15+
const result = {};
16+
const field = pareCallBack(s);
17+
result[field[0]] = field[1];
18+
return result;
19+
}
20+
21+
function parseParamsField(s) {
22+
if (s === "") return null;
23+
const object = {};
24+
const allParamsArr = s.split(/&/);
25+
allParamsArr.forEach((element) => {
26+
const field = element.split(/=/);
27+
object[field[0]] = field[1];
28+
});
29+
30+
return object;
31+
}
32+
33+
const option = {
34+
header: (data) => {
35+
let ouput = {};
36+
if (typeof data === "string") {
37+
ouput = pareString(data);
38+
} else {
39+
data.forEach((element) => {
40+
ouput = {
41+
...ouput,
42+
...pareString(element, parseField),
43+
};
44+
});
45+
return ouput;
46+
}
47+
return ouput;
48+
},
49+
body: (data) => {
50+
if (typeof data === "string") {
51+
try {
52+
return JSON.parse(data);
53+
} catch {
54+
try {
55+
return parseParamsField(data);
56+
} catch {
57+
return data;
58+
}
59+
}
60+
} else {
61+
let ouput = {};
62+
data.forEach((element) => {
63+
ouput = {
64+
...ouput,
65+
...pareString(element, parseFieldWithEqual),
66+
};
67+
});
68+
return ouput;
69+
}
70+
},
71+
parseParamsField,
72+
};
73+
74+
export default option;

ui/src/utils/curlParser/matcher.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-disable @typescript-eslint/no-shadow */
2+
const option = {
3+
matchArgv(s) {
4+
// ref: https://stackoverflow.com/questions/366202/regex-for-splitting-a-string-using-space-when-not-surrounded-by-single-or-double
5+
return s
6+
.replace(/\\\n/g, " ")
7+
.match(/"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+/g)
8+
.map((s) => {
9+
if (
10+
(s.startsWith("'") && s.endsWith("'")) ||
11+
(s.startsWith('"') && s.endsWith('"'))
12+
) {
13+
// remove quotes on both sides
14+
return s.substring(1, s.length - 1);
15+
}
16+
return s;
17+
});
18+
},
19+
};
20+
export default option;

ui/src/utils/curlParser/option.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/* eslint-disable import/no-import-module-exports */
2+
import convertor from "./convertor";
3+
4+
const options = [
5+
{
6+
name: "url",
7+
alias: ["url", "curl"],
8+
description: "Url request",
9+
convertor: null,
10+
},
11+
{
12+
name: "cookie",
13+
alias: ["b", "cookie"],
14+
description:
15+
"<name=data> Supply cookie with request. If no =, then specifies the cookie file to use (see -c).",
16+
convertor: null,
17+
},
18+
{
19+
name: "cookie-jar",
20+
alias: ["c", "cookie-jar"],
21+
description: "<file name> File to save response cookies to.",
22+
convertor: null,
23+
},
24+
{
25+
name: "data",
26+
alias: ["d", "data", "data-raw", "data-urlencode", "data-binary"],
27+
description:
28+
"<data> Send specified data in POST request. Details provided below.",
29+
convertor: convertor.body,
30+
},
31+
/* -f, --fail Fail silently (don't output HTML error form if returned). */
32+
{
33+
name: "fail",
34+
alias: ["f", "fail"],
35+
description: "Fail silently (don't output HTML error form if returned).",
36+
convertor: null,
37+
},
38+
// -F, --form <name=content> Submit form data.
39+
{
40+
name: "form",
41+
alias: ["F", "form"],
42+
description: "<name=content> Submit form data.",
43+
convertor: null,
44+
},
45+
// -H, --header <header> Headers to supply with request.
46+
{
47+
name: "header",
48+
alias: ["H", "header"],
49+
description: "<header> Headers to supply with request.",
50+
convertor: convertor.header,
51+
},
52+
53+
// -i, --include Include HTTP headers in the output.
54+
{
55+
name: "include",
56+
alias: ["i", "include"],
57+
description: "Include HTTP headers in the output.",
58+
convertor: null,
59+
},
60+
61+
// -I, --head Fetch headers only.
62+
{
63+
name: "head",
64+
alias: ["I", "head"],
65+
description: "Fetch headers only.",
66+
convertor: null,
67+
},
68+
69+
// -k, --insecure Allow insecure connections to succeed.
70+
{
71+
name: "insecure",
72+
alias: ["k", "insecure"],
73+
description: "Allow insecure connections to succeed.",
74+
convertor: null,
75+
},
76+
77+
// -L, --location Follow redirects.
78+
{
79+
name: "location",
80+
alias: ["L", "location"],
81+
description: "v",
82+
convertor: null,
83+
},
84+
85+
// -o, --output <file> Write output to . Can use --create-dirs in conjunction with this to create any directories specified in the -o path.
86+
{
87+
name: "output",
88+
alias: ["o", "output"],
89+
description:
90+
"<file> Write output to . Can use --create-dirs in conjunction with this to create any directories specified in the -o path.",
91+
convertor: null,
92+
},
93+
94+
// -O, --remote-name Write output to file named like the remote file (only writes to current directory).
95+
{
96+
name: "remote-name",
97+
alias: ["remote-name", "O"],
98+
description:
99+
"Write output to file named like the remote file (only writes to current directory).",
100+
convertor: null,
101+
},
102+
103+
// -s, --silent Silent (quiet) mode. Use with -S to force it to show errors.
104+
{
105+
name: "silent",
106+
alias: ["s", "silent"],
107+
description: "Silent (quiet) mode. Use with -S to force it to show errors.",
108+
convertor: null,
109+
},
110+
111+
// -v, --verbose Provide more information (useful for debugging).
112+
{
113+
name: "verbose",
114+
alias: ["v", "verbose"],
115+
description: "Provide more information (useful for debugging).",
116+
convertor: null,
117+
},
118+
119+
// -w, --write-out <format> Make curl display information on stdout after a completed transfer. See man page for more details on available variables. Convenient way to force curl to append a newline to output: -w "\n" (can add to ~/.curlrc).
120+
{
121+
name: "write-out",
122+
alias: ["write-out", "w"],
123+
description:
124+
'<format> Make curl display information on stdout after a completed transfer. See man page for more details on available variables. Convenient way to force curl to append a newline to output: -w "\n" (can add to ~/.curlrc).',
125+
convertor: null,
126+
},
127+
128+
// -X, --request The request method to use.
129+
{
130+
name: "method",
131+
alias: ["X", "request"],
132+
description: "The request method to use.",
133+
convertor: null,
134+
},
135+
136+
// -A, --user-agent <name>
137+
{
138+
name: "user-agent",
139+
alias: ["A", "user-agent"],
140+
description: "Specify the User-Agent send to the HTTP server.",
141+
convertor: null,
142+
},
143+
144+
// -e, --referer <URL>
145+
{
146+
name: "referer",
147+
alias: ["e", "referer"],
148+
description: 'Sends the "Referrer Page" information to the HTTP server.',
149+
convertor: null,
150+
},
151+
];
152+
153+
export default options;

ui/src/utils/curlParser/pare-json.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* eslint-disable import/no-import-module-exports */
2+
/* eslint-disable no-param-reassign */
3+
/* eslint-disable no-multi-assign */
4+
/* eslint-disable @typescript-eslint/no-shadow */
5+
// eslint-disable-next-line import/no-extraneous-dependencies
6+
import minimistParser from "minimist";
7+
import convertor from "./convertor";
8+
import options from "./option";
9+
import matcher from "./matcher";
10+
11+
export function parse(data) {
12+
if (typeof data === "string" || data instanceof String) {
13+
// minimistParser cannot parse from string
14+
// parse string to argvs array for minimistParser
15+
data = matcher.matchArgv(data);
16+
}
17+
const argv = minimistParser(data);
18+
19+
const result = {};
20+
21+
if (argv._[1]) {
22+
result.url = argv._[1].replace(/'/g, "");
23+
}
24+
25+
options.forEach((element) => {
26+
const { alias } = element;
27+
const value = alias
28+
.map((element) => argv[element])
29+
.filter((element) => element)[0];
30+
if (value) {
31+
if (element.convertor) {
32+
result[element.name] = element.convertor(value);
33+
} else {
34+
result[element.name] = value;
35+
}
36+
}
37+
});
38+
39+
if (result.url) {
40+
const url = new URL(result.url);
41+
result.url = url.origin + url.pathname;
42+
const params = new URLSearchParams(url.search);
43+
if (Array.from(params).length) {
44+
result.params = convertor.parseParamsField(params.toString());
45+
}
46+
}
47+
48+
if (!result.method) {
49+
// When there is a "data" parameter, the default is "post" request mode
50+
result.method = result.data ? "POST" : "GET";
51+
}
52+
53+
return result;
54+
}

ui/src/utils/curlToRequest.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,13 @@
1+
/* eslint-disable import/extensions */
12
// eslint-disable-next-line import/no-extraneous-dependencies
2-
import * as parse from "@bany/curl-to-json";
3-
4-
// TODO: @bany/curl-to-json library failed to parse header if there is no space between key and value. so added this patch
5-
const headerFix = (payload: Record<string, string>) => {
6-
return Object.keys(payload || {}).reduce(
7-
(acc: Record<string, string>, key: string) => {
8-
if (!payload[key]) {
9-
if (key.includes(":")) {
10-
const [mapKey, value] = key.split(":");
11-
acc[mapKey] = value;
12-
}
13-
} else {
14-
acc[key] = payload[key];
15-
}
16-
return acc;
17-
},
18-
{} as Record<string, string>
19-
);
20-
};
3+
import { parse } from "./curlParser/pare-json.js";
214

225
export const convertToCurl = (curl: string) => {
236
try {
247
const payload = parse(curl) as any;
258
return {
269
...payload,
27-
header: headerFix(payload.header),
10+
url: payload.url ? payload.url : payload.location,
2811
};
2912
} catch (e) {
3013
throw new Error("Error while parsing curl");

0 commit comments

Comments
 (0)