From c50b88d60dd152a228b237703dfb05617c62287a Mon Sep 17 00:00:00 2001 From: Luiz Fonseca Date: Wed, 4 Oct 2023 22:07:26 +0200 Subject: [PATCH 1/4] fix: missing typescript module on npm build script --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9aaaf23f..85e3e577 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "jest": "^29.2.0", "pretty-quick": "^3.1.3", "randomstring": "^1.2.2", - "ts-jest": "^29.0.5" + "ts-jest": "^29.0.5", + "typescript": "^5.2.2" }, "scripts": { "dev:web": "npm run dev --workspace=packages/bruno-app", From f7eb325e1123369af403a52411b246ac8a5ef1e6 Mon Sep 17 00:00:00 2001 From: Luiz Fonseca Date: Wed, 4 Oct 2023 22:08:25 +0200 Subject: [PATCH 2/4] fix: husky pre-commit missing correct prettier version --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 85e3e577..67faaf11 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@playwright/test": "^1.27.1", "husky": "^8.0.3", "jest": "^29.2.0", + "prettier": "^2.0.2", "pretty-quick": "^3.1.3", "randomstring": "^1.2.2", "ts-jest": "^29.0.5", From e1bf475f1fd2fb83744897a5afaa54781adb09f0 Mon Sep 17 00:00:00 2001 From: Luiz Fonseca Date: Wed, 4 Oct 2023 22:09:11 +0200 Subject: [PATCH 3/4] chore: pretty-quick fixes --- .../src/components/Sidebar/CreateCollection/index.js | 9 +++++---- .../bruno-app/src/utils/importers/insomnia-collection.js | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js b/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js index 9b56ca1b..bfe59ae8 100644 --- a/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js +++ b/packages/bruno-app/src/components/Sidebar/CreateCollection/index.js @@ -29,9 +29,7 @@ const CreateCollection = ({ onClose }) => { .max(50, 'must be 50 characters or less') .matches(/^[\w\-. ]+$/, 'Folder name contains invalid characters') .required('folder name is required'), - collectionLocation: Yup.string() - .min(1, 'location is required') - .required('location is required'), + collectionLocation: Yup.string().min(1, 'location is required').required('location is required') }), onSubmit: (values) => { dispatch(createCollection(values.collectionName, values.collectionFolderName, values.collectionLocation)) @@ -116,7 +114,10 @@ const CreateCollection = ({ onClose }) => { { return nameSuffix; }, 0); return nameSuffix !== 0 ? `${item.name}_${nameSuffix}` : item.name; -} +}; const transformInsomniaRequestItem = (request, index, allRequests) => { const name = addSuffixToDuplicateName(request, index, allRequests); From 6ef7891f8a1130173cc80a2e5a660de6c68052b5 Mon Sep 17 00:00:00 2001 From: Luiz Fonseca Date: Wed, 4 Oct 2023 22:09:48 +0200 Subject: [PATCH 4/4] fix(network): use interceptors when measuring request duration --- packages/bruno-app/src/utils/network/index.js | 4 +- .../src/ipc/network/axios-instance.js | 38 +++++++++++++++++++ .../bruno-electron/src/ipc/network/index.js | 18 +++++++-- 3 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 packages/bruno-electron/src/ipc/network/axios-instance.js diff --git a/packages/bruno-app/src/utils/network/index.js b/packages/bruno-app/src/utils/network/index.js index abc5583f..f4af7092 100644 --- a/packages/bruno-app/src/utils/network/index.js +++ b/packages/bruno-app/src/utils/network/index.js @@ -1,10 +1,8 @@ export const sendNetworkRequest = async (item, collection, environment, collectionVariables) => { return new Promise((resolve, reject) => { if (['http-request', 'graphql-request'].includes(item.type)) { - const timeStart = Date.now(); sendHttpRequest(item, collection, environment, collectionVariables) .then((response) => { - const timeEnd = Date.now(); resolve({ state: 'success', data: response.data, @@ -12,7 +10,7 @@ export const sendNetworkRequest = async (item, collection, environment, collecti size: response.headers['content-length'] || 0, status: response.status, statusText: response.statusText, - duration: timeEnd - timeStart + duration: response.duration }); }) .catch((err) => reject(err)); diff --git a/packages/bruno-electron/src/ipc/network/axios-instance.js b/packages/bruno-electron/src/ipc/network/axios-instance.js new file mode 100644 index 00000000..f4abd839 --- /dev/null +++ b/packages/bruno-electron/src/ipc/network/axios-instance.js @@ -0,0 +1,38 @@ +const axios = require('axios'); + +/** + * Function that configures axios with timing interceptors + * Important to note here that the timings are not completely accurate. + * @see https://github.com/axios/axios/issues/695 + * @returns {import('axios').AxiosStatic} + */ +function makeAxiosInstance() { + /** @type {import('axios').AxiosStatic} */ + const instance = axios.create(); + + instance.interceptors.request.use((config) => { + config.headers['request-start-time'] = Date.now(); + return config; + }); + + instance.interceptors.response.use( + (response) => { + const end = Date.now(); + const start = response.config.headers['request-start-time']; + response.headers['request-duration'] = end - start; + return response; + }, + (error) => { + const end = Date.now(); + const start = error.config.headers['request-start-time']; + error.response.headers['request-duration'] = end - start; + return Promise.reject(error); + } + ); + + return instance; +} + +module.exports = { + makeAxiosInstance +}; diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 6c1bec01..d79ec346 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -15,6 +15,7 @@ const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper'); const { getPreferences } = require('../../store/preferences'); const { getProcessEnvVars } = require('../../store/process-env'); const { getBrunoConfig } = require('../../store/bruno-config'); +const { makeAxiosInstance } = require('./axios-instance'); // override the default escape function to prevent escaping Mustache.escape = function (value) { @@ -240,7 +241,10 @@ const registerNetworkIpc = (mainWindow) => { }); } - const response = await axios(request); + const axiosInstance = makeAxiosInstance(); + + /** @type {import('axios').AxiosResponse} */ + const response = await axiosInstance(request); // run post-response vars const postResponseVars = get(request, 'vars.res', []); @@ -343,12 +347,16 @@ const registerNetworkIpc = (mainWindow) => { } deleteCancelToken(cancelTokenUid); + // Prevents the duration on leaking to the actual result + const requestDuration = response.headers.get('request-duration'); + response.headers.delete('request-duration'); return { status: response.status, statusText: response.statusText, headers: response.headers, - data: response.data + data: response.data, + duration: requestDuration }; } catch (error) { // todo: better error handling @@ -416,11 +424,15 @@ const registerNetworkIpc = (mainWindow) => { }); } + // Prevents the duration from leaking to the actual result + const requestDuration = error.response.headers.get('request-duration'); + error.response.headers.delete('request-duration'); return { status: error.response.status, statusText: error.response.statusText, headers: error.response.headers, - data: error.response.data + data: error.response.data, + duration: requestDuration ?? 0 }; }