Skip to content

Commit 068aea0

Browse files
committed
v1.4.0
1 parent 2509d0c commit 068aea0

File tree

10 files changed

+176
-6
lines changed

10 files changed

+176
-6
lines changed

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "OpenAPI DevTools",
4-
"version": "1.3.3",
4+
"version": "1.4.0",
55
"devtools_page": "index.html",
66
"permissions": [],
77
"icons": {

package-lock.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"cookie": "^0.6.0",
2020
"copy-to-clipboard": "^3.3.3",
2121
"decode-uri-component": "^0.4.1",
22+
"fast-querystring": "^1.1.2",
2223
"framer-motion": "^10.16.4",
2324
"fuse.js": "^6.6.2",
2425
"genson-js": "^0.0.8",

resources/dist.zip

7.81 KB
Binary file not shown.

src/lib/RequestStore.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,21 @@ it("parameterisation works after export and import", () => {
211211
// @ts-expect-error accessing private property
212212
expect(store.leafMap).toEqual(expected);
213213
});
214+
215+
it("parameterisation works after export and import", () => {
216+
const store = new RequestStore();
217+
const req = createSimpleRequest(`${base}/1/2/a`);
218+
store.insert(req, { foo: 1 });
219+
store.parameterise(2, "/1/2/a", host);
220+
const exported = store.export();
221+
store.clear();
222+
store.import(exported);
223+
store.insert(req, { foo: 1 });
224+
const expected = {
225+
[host]: {
226+
'/1/2/:param2': expect.any(Object),
227+
}
228+
};
229+
// @ts-expect-error accessing private property
230+
expect(store.leafMap).toEqual(expected);
231+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import type { Entry } from "har-format";
2+
3+
const postXWWWFormUrlEncoded: Entry = {
4+
_priority: "VeryHigh",
5+
_resourceType: "document",
6+
cache: {},
7+
connection: "17359",
8+
pageref: "page_10",
9+
request: {
10+
method: "POST",
11+
url: "https://httpbin.org/post",
12+
httpVersion: "http/2.0",
13+
headers: [],
14+
queryString: [],
15+
cookies: [],
16+
headersSize: -1,
17+
bodySize: 94,
18+
postData: {
19+
mimeType: "application/x-www-form-urlencoded",
20+
text: "custname=asdf&custtel=sadf&custemail=&size=medium&topping=cheese&delivery=11%3A00&comments=sdg",
21+
},
22+
},
23+
response: {
24+
status: 200,
25+
statusText: "",
26+
httpVersion: "http/2.0",
27+
headers: [],
28+
cookies: [],
29+
content: {
30+
size: 1411,
31+
mimeType: "application/json",
32+
},
33+
redirectURL: "",
34+
headersSize: -1,
35+
bodySize: -1,
36+
_transferSize: 1566,
37+
},
38+
serverIPAddress: "75.101.210.237",
39+
startedDateTime: "2023-11-26T03:21:54.665Z",
40+
time: 1121.7940000324434,
41+
timings: {
42+
blocked: 197.47300002474338,
43+
dns: 0.007999999999981355,
44+
ssl: 348.39799999999997,
45+
connect: 615.2149999999999,
46+
send: 0.31799999999998363,
47+
wait: 307.29200002782795,
48+
receive: 1.4879999798722565,
49+
},
50+
};
51+
52+
export default postXWWWFormUrlEncoded;

src/lib/store-helpers/create-leaf.test.ts

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,81 @@
11
import { it, expect } from "vitest";
22
import { defaultOptions } from "./persist-options";
33
import postJson from "../__fixtures__/post-application-json";
4+
import postXWWWFormUrlEncoded from "../__fixtures__/post-application-x-www-form-urlencoded";
45
import createLeaf, { Params } from "./create-leaf";
56

6-
it("creates a leaf", () => {
7+
it("creates a leaf when request mime = application/x-www-form-urlencoded", () => {
8+
const harRequest = postXWWWFormUrlEncoded;
9+
const responseBody: Params["responseBody"] = { test: 1 };
10+
const options = defaultOptions;
11+
const leaf = createLeaf({ harRequest, responseBody, options });
12+
expect(leaf).toEqual({
13+
pathname: "/post",
14+
methods: {
15+
POST: {
16+
"200": {
17+
request: {
18+
"application/x-www-form-urlencoded": {
19+
body: {
20+
type: "object",
21+
properties: {
22+
custname: {
23+
type: "string",
24+
},
25+
custtel: {
26+
type: "string",
27+
},
28+
custemail: {
29+
type: "string",
30+
},
31+
size: {
32+
type: "string",
33+
},
34+
topping: {
35+
type: "string",
36+
},
37+
delivery: {
38+
type: "string",
39+
},
40+
comments: {
41+
type: "string",
42+
},
43+
},
44+
required: [
45+
"custname",
46+
"custtel",
47+
"custemail",
48+
"size",
49+
"topping",
50+
"delivery",
51+
"comments",
52+
],
53+
},
54+
},
55+
},
56+
requestHeaders: undefined,
57+
response: {
58+
"application/json": {
59+
body: {
60+
type: "object",
61+
properties: {
62+
test: {
63+
type: "integer",
64+
},
65+
},
66+
required: ["test"],
67+
},
68+
},
69+
},
70+
responseHeaders: undefined,
71+
queryParameters: undefined,
72+
},
73+
},
74+
},
75+
});
76+
});
77+
78+
it("creates a leaf when mime = application/json for req and res", () => {
779
const harRequest = postJson;
880
const responseBody: Params["responseBody"] = { test: 1 };
981
const options = defaultOptions;

src/lib/store-helpers/create-leaf.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,24 @@ import determineAuthFromHAR from "./authentication";
99
import { filterIgnoreHeaders } from "../../utils/headers";
1010
import type { Options } from "../RequestStore";
1111
import type { Entry } from "har-format";
12+
import qs from 'fast-querystring';
13+
14+
const APPLICATION_JSON = "application/json";
15+
const APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
1216

1317
export type Params = {
1418
harRequest: Entry;
1519
responseBody: JSONType;
1620
options: Options;
1721
};
1822

23+
const parseRequestBody = (harRequest: Entry): JSONType => {
24+
const { mimeType, text } = harRequest.request.postData || {};
25+
if (mimeType === APPLICATION_JSON) return parseJSON(text);
26+
else if (mimeType === APPLICATION_X_WWW_FORM_URLENCODED && text) return qs.parse(text) as JSONType;
27+
return null;
28+
};
29+
1930
function createLeaf({ harRequest, responseBody, options }: Params): Leaf {
2031
const { enableMoreInfo } = options;
2132
const authentication = determineAuthFromHAR(harRequest);
@@ -27,7 +38,7 @@ function createLeaf({ harRequest, responseBody, options }: Params): Leaf {
2738
const statusCode = harRequest.response.status.toString();
2839
const requestMime = harRequest.request.postData?.mimeType;
2940
const responseMime = harRequest.response.content.mimeType;
30-
const requestBody = parseJSON(harRequest.request.postData?.text);
41+
const requestBody = parseRequestBody(harRequest);
3142
const requestHeaders = entriesToJSONType(harRequest.request.headers);
3243
const responseHeaders = entriesToJSONType(harRequest.response.headers);
3344
const queryParameters = entriesToJSONType(harRequest.request.queryString);

src/ui/ControlDynamic.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const ControlDynamic = () => {
8686
onClick={onClick}
8787
key={outerKey + part}
8888
>
89-
{`/${truncateMiddle(part, 7, 3, "...")}`}
89+
{`/${truncateMiddle(part, 12, 5, "...")}`}
9090
</WrapItem>
9191
</Tooltip>
9292
);

src/utils/helpers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const isValidJSONString = (content: string): boolean => {
3131
};
3232

3333
const validStatuses = new Set(["GET", "POST", "PUT", "DELETE", "PATCH"]);
34-
const validResourceTypes = new Set(["xhr", "fetch"]);
34+
const validResourceTypes = new Set(["xhr", "fetch", "document"]);
3535
const isValidStatus = (status: string) => validStatuses.has(status);
3636
export const isValidRequest = async (
3737
harRequest: chrome.devtools.network.Request
@@ -44,7 +44,9 @@ export const isValidRequest = async (
4444
if (didNotReachServer) return false;
4545
const content = await getContent(harRequest);
4646
const isNotJSON = harRequest.response.content.mimeType !== "application/json" && !isValidJSONString(content);
47-
if (isNotJSON) return false;
47+
const isNotXWWWFormUrlEncoded = harRequest.request.postData?.mimeType !== "application/x-www-form-urlencoded";
48+
const isNotValidMime = isNotJSON && isNotXWWWFormUrlEncoded;
49+
if (isNotValidMime) return false;
4850
const isNotValidStatus = !isValidStatus(harRequest.request.method);
4951
if (isNotValidStatus) return false;
5052
if (!isValidURL(harRequest.request.url)) return false;

0 commit comments

Comments
 (0)