diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index b033398a3..4bd83400b 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @helloanoop @maintainer-bruno @lohit-bruno @naman-bruno
+* @helloanoop @maintainer-bruno @bijin-bruno @lohit-bruno @naman-bruno
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index aaf5d1880..2a829098e 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -30,6 +30,7 @@ jobs:
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
npm run build --workspace=packages/bruno-converters
npm run build --workspace=packages/bruno-requests
+ npm run build --workspace=packages/bruno-filestore
- name: Lint Check
run: npm run lint
@@ -80,6 +81,7 @@ jobs:
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
npm run build --workspace=packages/bruno-converters
npm run build --workspace=packages/bruno-requests
+ npm run build --workspace=packages/bruno-filestore
- name: Run tests
run: |
@@ -125,6 +127,7 @@ jobs:
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
npm run build:bruno-converters
npm run build:bruno-requests
+ npm run build:bruno-filestore
- name: Run Playwright tests
run: |
diff --git a/assets/images/landing-2.png b/assets/images/landing-2.png
index 156d207e5..2d3fa7f12 100644
Binary files a/assets/images/landing-2.png and b/assets/images/landing-2.png differ
diff --git a/contributing.md b/contributing.md
index b72d71293..0c6a7d4a6 100644
--- a/contributing.md
+++ b/contributing.md
@@ -69,6 +69,7 @@ npm run build:bruno-query
npm run build:bruno-common
npm run build:bruno-converters
npm run build:bruno-requests
+npm run build:bruno-filestore
# bundle js sandbox libraries
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
diff --git a/e2e-tests/001-sanity-tests/001-home-screen.spec.ts b/e2e-tests/001-sanity-tests/001-home-screen.spec.ts
index d993fb7bc..326ff895c 100644
--- a/e2e-tests/001-sanity-tests/001-home-screen.spec.ts
+++ b/e2e-tests/001-sanity-tests/001-home-screen.spec.ts
@@ -2,4 +2,4 @@ import { test, expect } from '../../playwright';
test('Check if the logo on top left is visible', async ({ page }) => {
await expect(page.getByRole('button', { name: 'bruno' })).toBeVisible();
-});
\ No newline at end of file
+});
diff --git a/e2e-tests/002-cookies-tests/001-cookie-persistence.spec.ts b/e2e-tests/002-cookies-tests/001-cookie-persistence.spec.ts
new file mode 100644
index 000000000..beefb3b39
--- /dev/null
+++ b/e2e-tests/002-cookies-tests/001-cookie-persistence.spec.ts
@@ -0,0 +1,43 @@
+import { test, expect } from '../../playwright';
+
+test('should persist cookies across app restarts', async ({ createTmpDir, launchElectronApp }) => {
+ // Create a temporary user-data directory so we control where the cookies store file is written.
+ const userDataPath = await createTmpDir('cookie-persistence');
+
+ const app1 = await launchElectronApp({ userDataPath });
+ const page1 = await app1.firstWindow();
+ await page1.waitForSelector('[data-trigger="cookies"]');
+
+ // Open Cookies modal via the status-bar button.
+ await page1.click('[data-trigger="cookies"]');
+
+ // When no cookies are present the modal shows a centred "Add Cookie" button.
+ await page1.getByRole('button', { name: /Add Cookie/i }).click();
+
+ // Fill out the form.
+ await page1.fill('input[name="domain"]', 'example.com');
+ await page1.fill('input[name="path"]', '/');
+ await page1.fill('input[name="key"]', 'session');
+ await page1.fill('input[name="value"]', 'abc123');
+ await page1.check('input[name="secure"]');
+ await page1.check('input[name="httpOnly"]');
+
+ await page1.getByRole('button', { name: 'Save' }).click();
+
+ await expect(page1.getByText('example.com')).toBeVisible();
+
+ await app1.close();
+
+ // Second launch – verify the cookie was persisted and re-loaded
+ const app2 = await launchElectronApp({ userDataPath });
+ const page2 = await app2.firstWindow();
+
+ // Open the Cookies modal again.
+ await page2.waitForSelector('[data-trigger="cookies"]');
+ await page2.click('[data-trigger="cookies"]');
+
+ // The domain we added earlier should still be present.
+ await expect(page2.getByText('example.com')).toBeVisible();
+
+ await app2.close();
+});
diff --git a/e2e-tests/002-cookies-tests/002-corrupted-passkey.spec.ts b/e2e-tests/002-cookies-tests/002-corrupted-passkey.spec.ts
new file mode 100644
index 000000000..02c2a5010
--- /dev/null
+++ b/e2e-tests/002-cookies-tests/002-corrupted-passkey.spec.ts
@@ -0,0 +1,47 @@
+import { test, expect } from '../../playwright';
+import * as path from 'path';
+import * as fs from 'fs/promises';
+
+test('should handle corrupted passkey and still display saved cookie list', async ({ createTmpDir, launchElectronApp }) => {
+ const userDataPath = await createTmpDir('corrupted-passkey');
+
+ const app1 = await launchElectronApp({ userDataPath });
+ // 1. First run – add a cookie via the UI so `cookies.json` is created.
+ const page1 = await app1.firstWindow();
+
+ await page1.waitForSelector('[data-trigger="cookies"]');
+ await page1.click('[data-trigger="cookies"]');
+ await page1.getByRole('button', { name: /Add Cookie/i }).click();
+
+ await page1.fill('input[name="domain"]', 'example.com');
+ await page1.fill('input[name="path"]', '/');
+ await page1.fill('input[name="key"]', 'session');
+ await page1.fill('input[name="value"]', 'abc123');
+ await page1.check('input[name="secure"]');
+ await page1.check('input[name="httpOnly"]');
+
+ await page1.getByRole('button', { name: 'Save' }).click();
+
+ await expect(page1.getByText('example.com')).toBeVisible();
+
+ await app1.close();
+
+ // 2. Corrupt the encryptedPasskey in cookies.json
+ const cookiesFilePath = path.join(userDataPath, 'cookies.json');
+ const raw = await fs.readFile(cookiesFilePath, 'utf-8');
+ const cookiesJson = JSON.parse(raw);
+ cookiesJson.encryptedPasskey = 'deadbeef'; // clearly invalid value
+ await fs.writeFile(cookiesFilePath, JSON.stringify(cookiesJson, null, 2));
+
+ // 3. Second run – Bruno should recover and still list the cookie domain
+ const app2 = await launchElectronApp({ userDataPath });
+ const page2 = await app2.firstWindow();
+
+ await page2.waitForSelector('[data-trigger="cookies"]');
+ await page2.click('[data-trigger="cookies"]');
+
+ // The domain row should still be visible (even if cookie values are blank).
+ await expect(page2.getByText('example.com')).toBeVisible();
+
+ await app2.close();
+});
diff --git a/e2e-tests/persistent-env-tests/001-persistent-env-test.spec.ts b/e2e-tests/persistent-env-tests/001-persistent-env-test.spec.ts
new file mode 100644
index 000000000..e319e178f
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/001-persistent-env-test.spec.ts
@@ -0,0 +1,33 @@
+import { test, expect } from '../../playwright';
+
+test.describe.serial('Persistent Environment Test', () => {
+ test.setTimeout(2 * 10 * 1000);
+
+ test('add env using script', async ({ pageWithUserData: page, restartApp }) => {
+ await page.locator('#sidebar-collection-name').click();
+ await page.getByRole('button', { name: 'Save' }).click();
+ await page.getByText('ping', { exact: true }).click();
+ await page.getByText('No Environment').click();
+ await page.getByRole('tooltip').locator('div').filter({ hasText: 'Env' }).nth(3).click();
+ await page.locator('#send-request').getByRole('img').nth(2).click();
+ await page.waitForTimeout(1000);
+ await page.locator('div').filter({ hasText: /^Env$/ }).nth(3).click();
+ await page.getByText('Configure', { exact: true }).click();
+ await expect(page.getByRole('row', { name: 'persistent-env-test' }).getByRole('cell').nth(3)).toBeVisible();
+ await page.getByText('×').click();
+
+ const newApp = await restartApp();
+ const newPage = await newApp.firstWindow();
+ await newPage.locator('#sidebar-collection-name').click();
+ await newPage.getByRole('button', { name: 'Save' }).click();
+ await newPage.getByText('ping', { exact: true }).click();
+ await newPage.getByText('No Environment').click();
+ await newPage.getByRole('tooltip').locator('div').filter({ hasText: 'Env' }).nth(3).click();
+ await newPage.locator('div').filter({ hasText: /^Env$/ }).nth(3).click();
+ await newPage.getByText('Configure', { exact: true }).click();
+ await expect(newPage.getByRole('row', { name: 'persistent-env-test' }).getByRole('cell').nth(3)).toBeVisible();
+ await newPage.getByText('×').click();
+ await newPage.waitForTimeout(1000);
+ await newPage.close();
+ });
+});
diff --git a/e2e-tests/persistent-env-tests/002-env-test-without-persistence.spec.ts b/e2e-tests/persistent-env-tests/002-env-test-without-persistence.spec.ts
new file mode 100644
index 000000000..4be151bb0
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/002-env-test-without-persistence.spec.ts
@@ -0,0 +1,40 @@
+import { test, expect } from '../../playwright';
+
+test.describe.serial('Persistent Environment Test', () => {
+ test.setTimeout(2 * 10 * 1000);
+
+ test('add env using script', async ({ pageWithUserData: page, restartApp }) => {
+ await page.locator('#sidebar-collection-name').click();
+ await page.getByText('ping2', { exact: true }).click();
+ await page.getByText('Env', { exact: true }).click();
+ await page.getByText('Stage', { exact: true }).click();
+ await page.locator('#send-request').getByRole('img').nth(2).click();
+ await page.waitForTimeout(1000);
+ await page
+ .locator('div')
+ .filter({ hasText: /^Stage$/ })
+ .nth(3)
+ .click();
+ await page.getByText('Configure', { exact: true }).click();
+ await expect(page.getByRole('row', { name: 'persistent-env-test' }).getByRole('cell').nth(3)).toBeVisible();
+ await page.getByText('×').click();
+
+ const newApp = await restartApp();
+ const newPage = await newApp.firstWindow();
+ await newPage.locator('#sidebar-collection-name').click();
+ await newPage.getByRole('button', { name: 'Save' }).click();
+ await newPage.getByText('ping2', { exact: true }).click();
+ await newPage.getByText('No Environment').click();
+ await newPage.getByText('Stage').click();
+ await newPage
+ .locator('div')
+ .filter({ hasText: /^Stage$/ })
+ .nth(3)
+ .click();
+ await newPage.getByText('Configure', { exact: true }).click();
+ await expect(newPage.getByRole('row', { name: 'persistent-env-test' }).getByRole('cell').nth(3)).not.toBeVisible();
+ await newPage.getByText('×').click();
+ await newPage.waitForTimeout(1000);
+ await newPage.close();
+ });
+});
diff --git a/e2e-tests/persistent-env-tests/collection/bruno.json b/e2e-tests/persistent-env-tests/collection/bruno.json
new file mode 100644
index 000000000..fa729847c
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/collection/bruno.json
@@ -0,0 +1,5 @@
+{
+ "version": "1",
+ "name": "collection",
+ "type": "collection"
+}
\ No newline at end of file
diff --git a/e2e-tests/persistent-env-tests/collection/collection.bru b/e2e-tests/persistent-env-tests/collection/collection.bru
new file mode 100644
index 000000000..e69de29bb
diff --git a/e2e-tests/persistent-env-tests/collection/environments/Env.bru b/e2e-tests/persistent-env-tests/collection/environments/Env.bru
new file mode 100644
index 000000000..909243fd2
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/collection/environments/Env.bru
@@ -0,0 +1,4 @@
+vars {
+ host: https://testbench-sanity.usebruno.com
+ persistent-env-test: persistent-env-test-value
+}
diff --git a/e2e-tests/persistent-env-tests/collection/environments/Stage.bru b/e2e-tests/persistent-env-tests/collection/environments/Stage.bru
new file mode 100644
index 000000000..0b756aa68
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/collection/environments/Stage.bru
@@ -0,0 +1,3 @@
+vars {
+ host: https://testbench-sanity.usebruno.com
+}
\ No newline at end of file
diff --git a/e2e-tests/persistent-env-tests/collection/persist-env-request.bru b/e2e-tests/persistent-env-tests/collection/persist-env-request.bru
new file mode 100644
index 000000000..eefb4e827
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/collection/persist-env-request.bru
@@ -0,0 +1,15 @@
+meta {
+ name: ping2
+ type: http
+ seq: 1
+}
+
+get {
+ url: {{host}}/ping
+ body: none
+ auth: none
+}
+
+script:pre-request {
+ bru.setEnvVar("persistent-env-test", "persistent-env-test-value");
+}
\ No newline at end of file
diff --git a/e2e-tests/persistent-env-tests/collection/request.bru b/e2e-tests/persistent-env-tests/collection/request.bru
new file mode 100644
index 000000000..9ae6899c5
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/collection/request.bru
@@ -0,0 +1,15 @@
+meta {
+ name: ping
+ type: http
+ seq: 1
+}
+
+get {
+ url: {{host}}/ping
+ body: none
+ auth: none
+}
+
+script:pre-request {
+ bru.setEnvVar("persistent-env-test", "persistent-env-test-value", { persist: true });
+}
\ No newline at end of file
diff --git a/e2e-tests/persistent-env-tests/init-user-data/preferences.json b/e2e-tests/persistent-env-tests/init-user-data/preferences.json
new file mode 100644
index 000000000..f9c1fdc7e
--- /dev/null
+++ b/e2e-tests/persistent-env-tests/init-user-data/preferences.json
@@ -0,0 +1,6 @@
+{
+ "maximized": true,
+ "lastOpenedCollections": [
+ "{{projectRoot}}/e2e-tests/persistent-env-tests/collection"
+ ]
+}
\ No newline at end of file
diff --git a/eslint.config.js b/eslint.config.js
index 30930c550..2d136029b 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -5,7 +5,7 @@ const globals = require("globals");
module.exports = defineConfig([
{
files: ["packages/bruno-app/**/*.{js,jsx,ts}"],
- ignores: ["**/*.config.js"],
+ ignores: ["**/*.config.js", "**/public/**/*"],
languageOptions: {
globals: {
...globals.browser,
@@ -13,7 +13,8 @@ module.exports = defineConfig([
global: false,
require: false,
Buffer: false,
- process: false
+ process: false,
+ ipcRenderer: false
},
parserOptions: {
ecmaFeatures: {
@@ -39,8 +40,60 @@ module.exports = defineConfig([
},
},
{
- files: ["packages/bruno-electron/**/*.{js}"],
+ files: ["packages/bruno-cli/**/*.js"],
ignores: ["**/*.config.js"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parserOptions: {
+ ecmaVersion: "latest"
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-common/**/*.ts"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parser: require("@typescript-eslint/parser"),
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ project: "./packages/bruno-common/tsconfig.json",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-converters/**/*.js"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-electron/**/*.js"],
+ ignores: ["**/*.config.js", "**/web/**/*"],
languageOptions: {
globals: {
...globals.node,
@@ -50,5 +103,98 @@ module.exports = defineConfig([
rules: {
"no-undef": "error",
},
- }
+ },
+ {
+ files: ["packages/bruno-filestore/**/*.ts"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parser: require("@typescript-eslint/parser"),
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ project: "./packages/bruno-filestore/tsconfig.json",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-js/**/*.js"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ window: false,
+ self: false,
+ HTMLElement: false,
+ typeDetectGlobalObject: false
+ },
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-lang/**/*.js"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-requests/**/*.ts"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parser: require("@typescript-eslint/parser"),
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ project: "./packages/bruno-requests/tsconfig.json",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
+ {
+ files: ["packages/bruno-requests/**/*.js"],
+ ignores: ["**/*.config.js", "**/dist/**/*"],
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ ...globals.jest,
+ },
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ },
+ },
+ rules: {
+ "no-undef": "error",
+ },
+ },
]);
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 577b1d843..de4683783 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,15 +18,18 @@
"packages/bruno-tests",
"packages/bruno-toml",
"packages/bruno-graphql-docs",
- "packages/bruno-requests"
+ "packages/bruno-requests",
+ "packages/bruno-filestore"
],
"devDependencies": {
"@faker-js/faker": "^7.6.0",
"@jest/globals": "^29.2.0",
"@playwright/test": "^1.51.1",
+ "@rollup/plugin-json": "^6.1.0",
"@types/jest": "^29.5.11",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.14.1",
+ "@typescript-eslint/parser": "^8.39.0",
"concurrently": "^8.2.2",
"eslint": "^9.26.0",
"fs-extra": "^11.1.1",
@@ -3515,7 +3518,6 @@
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
"integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^6.12.0",
@@ -3533,7 +3535,6 @@
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
@@ -3550,7 +3551,6 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
"license": "MIT"
},
"node_modules/@discoveryjs/json-ext": {
@@ -3567,7 +3567,6 @@
"version": "3.2.17",
"resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.17.tgz",
"integrity": "sha512-OcWImUI686w8LkghQj9R2ynZ2ME693Ek6L1SiaAgqGKzBaTIZw3fHDqN82Rcl+EU1Gm9EgkJ5KLIY/q5DCRbbA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"commander": "^5.0.0",
@@ -3585,7 +3584,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -3597,7 +3595,6 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -3618,7 +3615,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -3650,9 +3646,9 @@
}
},
"node_modules/@electron/get/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3709,296 +3705,6 @@
"node": ">= 4.0.0"
}
},
- "node_modules/@electron/notarize": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz",
- "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.1.1",
- "fs-extra": "^9.0.1",
- "promise-retry": "^2.0.1"
- },
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/@electron/notarize/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@electron/notarize/node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@electron/notarize/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@electron/osx-sign": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.1.tgz",
- "integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "compare-version": "^0.1.2",
- "debug": "^4.3.4",
- "fs-extra": "^10.0.0",
- "isbinaryfile": "^4.0.8",
- "minimist": "^1.2.6",
- "plist": "^3.0.5"
- },
- "bin": {
- "electron-osx-flat": "bin/electron-osx-flat.js",
- "electron-osx-sign": "bin/electron-osx-sign.js"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/@electron/osx-sign/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@electron/osx-sign/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@electron/osx-sign/node_modules/isbinaryfile": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
- "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/gjtorikian/"
- }
- },
- "node_modules/@electron/osx-sign/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@electron/rebuild": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.6.1.tgz",
- "integrity": "sha512-f6596ZHpEq/YskUd8emYvOUne89ij8mQgjYFA5ru25QwbrRO+t1SImofdDv7kKOuWCmVOuU5tvfkbgGxIl3E/w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@malept/cross-spawn-promise": "^2.0.0",
- "chalk": "^4.0.0",
- "debug": "^4.1.1",
- "detect-libc": "^2.0.1",
- "fs-extra": "^10.0.0",
- "got": "^11.7.0",
- "node-abi": "^3.45.0",
- "node-api-version": "^0.2.0",
- "node-gyp": "^9.0.0",
- "ora": "^5.1.0",
- "read-binary-file-arch": "^1.0.6",
- "semver": "^7.3.5",
- "tar": "^6.0.5",
- "yargs": "^17.0.1"
- },
- "bin": {
- "electron-rebuild": "lib/cli.js"
- },
- "engines": {
- "node": ">=12.13.0"
- }
- },
- "node_modules/@electron/rebuild/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@electron/rebuild/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@electron/rebuild/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@electron/rebuild/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@electron/rebuild/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@electron/universal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz",
- "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@electron/asar": "^3.2.7",
- "@malept/cross-spawn-promise": "^2.0.0",
- "debug": "^4.3.1",
- "dir-compare": "^4.2.0",
- "fs-extra": "^11.1.1",
- "minimatch": "^9.0.3",
- "plist": "^3.1.0"
- },
- "engines": {
- "node": ">=16.4"
- }
- },
- "node_modules/@electron/universal/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@electron/universal/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@electron/universal/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
@@ -4369,13 +4075,6 @@
"integrity": "sha512-weN3E+rq0Xb3Z93VHJ+Rc7WOQX9ETJPTAJ+gDcaMHtjft67L58sfS65rAjC5tZUXQ2FdZ/V1/sSzCwZ6v05kJw==",
"license": "OFL-1.1"
},
- "node_modules/@gar/promisify": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
- "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@graphiql/react": {
"version": "0.26.2",
"resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.26.2.tgz",
@@ -4489,6 +4188,37 @@
}
}
},
+ "node_modules/@grpc/grpc-js": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.3.tgz",
+ "integrity": "sha512-FTXHdOoPbZrBjlVLHuKbDZnsTxXv2BlHF57xw6LuThXacXvtkahEPED0CKMk6obZDf65Hv4k3z62eyPNpvinIg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@grpc/proto-loader": "^0.7.13",
+ "@js-sdsl/ordered-map": "^4.4.2"
+ },
+ "engines": {
+ "node": ">=12.10.0"
+ }
+ },
+ "node_modules/@grpc/proto-loader": {
+ "version": "0.7.15",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz",
+ "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "lodash.camelcase": "^4.3.0",
+ "long": "^5.0.0",
+ "protobufjs": "^7.2.5",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@headlessui/react": {
"version": "1.7.19",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz",
@@ -4582,7 +4312,6 @@
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
@@ -4600,7 +4329,6 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -4613,7 +4341,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@@ -4626,14 +4353,12 @@
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "dev": true,
"license": "MIT"
},
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
@@ -4651,7 +4376,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
@@ -4667,7 +4391,6 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
@@ -5273,6 +4996,16 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@js-sdsl/ordered-map": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
+ "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/js-sdsl"
+ }
+ },
"node_modules/@jsep-plugin/assignment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz",
@@ -5297,34 +5030,10 @@
"jsep": "^0.4.0||^1.0.0"
}
},
- "node_modules/@malept/cross-spawn-promise": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz",
- "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/malept"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
- }
- ],
- "license": "Apache-2.0",
- "dependencies": {
- "cross-spawn": "^7.0.1"
- },
- "engines": {
- "node": ">= 12.13.0"
- }
- },
"node_modules/@malept/flatpak-bundler": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz",
"integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"debug": "^4.1.1",
@@ -5340,7 +5049,6 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -5358,7 +5066,6 @@
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"at-least-node": "^1.0.0",
@@ -5374,7 +5081,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/@mapbox/node-pre-gyp": {
@@ -5819,124 +5525,6 @@
"node": ">= 8"
}
},
- "node_modules/@npmcli/fs": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
- "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@gar/promisify": "^1.1.3",
- "semver": "^7.3.5"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/@npmcli/fs/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@npmcli/move-file": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
- "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
- "deprecated": "This functionality has been moved to @npmcli/fs",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mkdirp": "^1.0.4",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@npmcli/move-file/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/@parcel/watcher": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz",
@@ -6257,7 +5845,6 @@
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "dev": true,
"license": "MIT",
"optional": true,
"engines": {
@@ -6359,6 +5946,70 @@
"node": ">=16.9"
}
},
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/@radix-ui/primitive": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
@@ -7052,6 +6703,27 @@
}
}
},
+ "node_modules/@rollup/plugin-json": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz",
+ "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rollup/plugin-node-resolve": {
"version": "15.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
@@ -8254,7 +7926,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 10"
@@ -8348,7 +8019,6 @@
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/ms": "*"
@@ -8386,12 +8056,17 @@
"version": "9.0.13",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
+ "node_modules/@types/google-protobuf": {
+ "version": "3.15.12",
+ "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.12.tgz",
+ "integrity": "sha512-40um9QqwHjRS92qnOaDpL7RmDK15NuZYo9HihiJRbYkMQZlWnuH8AdvbMy8/o6lgLmKbDUKa+OALCltHdbOTpQ==",
+ "license": "MIT"
+ },
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -8542,6 +8217,15 @@
"@types/lodash": "*"
}
},
+ "node_modules/@types/lodash.set": {
+ "version": "4.3.9",
+ "resolved": "https://registry.npmjs.org/@types/lodash.set/-/lodash.set-4.3.9.tgz",
+ "integrity": "sha512-KOxyNkZpbaggVmqbpr82N2tDVTx05/3/j0f50Es1prxrWB0XYf9p3QNxqcbWb7P1Q9wlvsUSlCFnwlPCIJ46PQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/lodash": "*"
+ }
+ },
"node_modules/@types/markdown-it": {
"version": "12.2.3",
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
@@ -8564,14 +8248,12 @@
"version": "0.7.34",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==",
- "dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.15.17",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz",
"integrity": "sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@@ -8703,6 +8385,253 @@
"@types/node": "*"
}
},
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.39.0.tgz",
+ "integrity": "sha512-g3WpVQHngx0aLXn6kfIYCZxM6rRJlWzEkVpqEFLT3SgEDsp9cpCbxxgwnE504q4H+ruSDh/VGS6nqZIDynP+vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/typescript-estree": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.0.tgz",
+ "integrity": "sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.39.0",
+ "@typescript-eslint/types": "^8.39.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/project-service/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.0.tgz",
+ "integrity": "sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.0.tgz",
+ "integrity": "sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.0.tgz",
+ "integrity": "sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.0.tgz",
+ "integrity": "sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.39.0",
+ "@typescript-eslint/tsconfig-utils": "8.39.0",
+ "@typescript-eslint/types": "8.39.0",
+ "@typescript-eslint/visitor-keys": "8.39.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.39.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.0.tgz",
+ "integrity": "sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.39.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
"node_modules/@usebruno/app": {
"resolved": "packages/bruno-app",
"link": true
@@ -8725,6 +8654,10 @@
"integrity": "sha512-khvEnRF6/UVDw4df06j+6lFWGNDYWlcWnxfmEgU2o/CdsGY291NC1Cexz99ud7sbGBQP2d8JUXZe4zXPkGNJpQ==",
"license": "MIT"
},
+ "node_modules/@usebruno/filestore": {
+ "resolved": "packages/bruno-filestore",
+ "link": true
+ },
"node_modules/@usebruno/graphql-docs": {
"resolved": "packages/bruno-graphql-docs",
"link": true
@@ -9047,7 +8980,6 @@
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
- "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@@ -9071,7 +9003,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz",
"integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==",
- "dev": true,
"license": "MIT"
},
"node_modules/abab": {
@@ -9086,8 +9017,8 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
- "devOptional": true,
- "license": "ISC"
+ "license": "ISC",
+ "optional": true
},
"node_modules/abort-controller": {
"version": "3.0.0",
@@ -9175,33 +9106,6 @@
"node": ">= 14"
}
},
- "node_modules/agentkeepalive": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
- "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "humanize-ms": "^1.2.1"
- },
- "engines": {
- "node": ">= 8.0.0"
- }
- },
- "node_modules/aggregate-error": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
- "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "clean-stack": "^2.0.0",
- "indent-string": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ajv": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
@@ -9253,7 +9157,6 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
"license": "MIT",
"peerDependencies": {
"ajv": "^6.9.1"
@@ -9340,114 +9243,6 @@
"node": ">= 8"
}
},
- "node_modules/app-builder-bin": {
- "version": "5.0.0-alpha.10",
- "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.10.tgz",
- "integrity": "sha512-Ev4jj3D7Bo+O0GPD2NMvJl+PGiBAfS7pUGawntBNpCbxtpncfUixqFj9z9Jme7V7s3LBGqsWZZP54fxBX3JKJw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/app-builder-lib": {
- "version": "25.1.8",
- "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-25.1.8.tgz",
- "integrity": "sha512-pCqe7dfsQFBABC1jeKZXQWhGcCPF3rPCXDdfqVKjIeWBcXzyC1iOWZdfFhGl+S9MyE/k//DFmC6FzuGAUudNDg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@develar/schema-utils": "~2.6.5",
- "@electron/notarize": "2.5.0",
- "@electron/osx-sign": "1.3.1",
- "@electron/rebuild": "3.6.1",
- "@electron/universal": "2.0.1",
- "@malept/flatpak-bundler": "^0.4.0",
- "@types/fs-extra": "9.0.13",
- "async-exit-hook": "^2.0.1",
- "bluebird-lst": "^1.0.9",
- "builder-util": "25.1.7",
- "builder-util-runtime": "9.2.10",
- "chromium-pickle-js": "^0.2.0",
- "config-file-ts": "0.2.8-rc1",
- "debug": "^4.3.4",
- "dotenv": "^16.4.5",
- "dotenv-expand": "^11.0.6",
- "ejs": "^3.1.8",
- "electron-publish": "25.1.7",
- "form-data": "^4.0.0",
- "fs-extra": "^10.1.0",
- "hosted-git-info": "^4.1.0",
- "is-ci": "^3.0.0",
- "isbinaryfile": "^5.0.0",
- "js-yaml": "^4.1.0",
- "json5": "^2.2.3",
- "lazy-val": "^1.0.5",
- "minimatch": "^10.0.0",
- "resedit": "^1.7.0",
- "sanitize-filename": "^1.6.3",
- "semver": "^7.3.8",
- "tar": "^6.1.12",
- "temp-file": "^3.4.0"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "dmg-builder": "25.1.8",
- "electron-builder-squirrel-windows": "25.1.8"
- }
- },
- "node_modules/app-builder-lib/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/app-builder-lib/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/app-builder-lib/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/app-builder-lib/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/append-field": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
@@ -9458,8 +9253,8 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
- "devOptional": true,
- "license": "ISC"
+ "license": "ISC",
+ "optional": true
},
"node_modules/arcsecond": {
"version": "5.0.0",
@@ -9467,36 +9262,6 @@
"integrity": "sha512-J/fHdyadnsIencRsM6oUSsraCKG+Ni9Udcgr/eusxjTzX3SEQtCUQSpP0YtImFPfIK6DdT1nqwN0ng4FqNmwgA==",
"license": "MIT"
},
- "node_modules/are-we-there-yet": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
- "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
- "deprecated": "This package is no longer supported.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "delegates": "^1.0.0",
- "readable-stream": "^3.6.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/are-we-there-yet/node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/arg": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
@@ -9647,14 +9412,12 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
- "dev": true,
"license": "MIT"
},
"node_modules/async-exit-hook": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
"integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@@ -10100,45 +9863,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
- "node_modules/bl/node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/bluebird": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
- "dev": true,
"license": "MIT"
},
"node_modules/bluebird-lst": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz",
"integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"bluebird": "^3.5.5"
@@ -10227,7 +9961,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@@ -10501,6 +10234,18 @@
"node": "*"
}
},
+ "node_modules/buffer-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz",
+ "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
@@ -10520,127 +10265,19 @@
"dev": true,
"license": "MIT"
},
- "node_modules/builder-util": {
- "version": "25.1.7",
- "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-25.1.7.tgz",
- "integrity": "sha512-7jPjzBwEGRbwNcep0gGNpLXG9P94VA3CPAZQCzxkFXiV2GMQKlziMbY//rXPI7WKfhsvGgFXjTcXdBEwgXw9ww==",
+ "node_modules/builtin-modules": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz",
+ "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@types/debug": "^4.1.6",
- "7zip-bin": "~5.2.0",
- "app-builder-bin": "5.0.0-alpha.10",
- "bluebird-lst": "^1.0.9",
- "builder-util-runtime": "9.2.10",
- "chalk": "^4.1.2",
- "cross-spawn": "^7.0.3",
- "debug": "^4.3.4",
- "fs-extra": "^10.1.0",
- "http-proxy-agent": "^7.0.0",
- "https-proxy-agent": "^7.0.0",
- "is-ci": "^3.0.0",
- "js-yaml": "^4.1.0",
- "source-map-support": "^0.5.19",
- "stat-mode": "^1.0.0",
- "temp-file": "^3.4.0"
- }
- },
- "node_modules/builder-util-runtime": {
- "version": "9.2.10",
- "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz",
- "integrity": "sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4",
- "sax": "^1.2.4"
- },
"engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/builder-util-runtime/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/builder-util-runtime/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/builder-util/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
+ "node": ">=18.20"
},
"funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/builder-util/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/builder-util/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/builder-util/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@@ -10668,122 +10305,6 @@
"node": ">= 0.8"
}
},
- "node_modules/cacache": {
- "version": "16.1.3",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
- "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@npmcli/fs": "^2.1.0",
- "@npmcli/move-file": "^2.0.0",
- "chownr": "^2.0.0",
- "fs-minipass": "^2.1.0",
- "glob": "^8.0.1",
- "infer-owner": "^1.0.4",
- "lru-cache": "^7.7.1",
- "minipass": "^3.1.6",
- "minipass-collect": "^1.0.2",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "mkdirp": "^1.0.4",
- "p-map": "^4.0.0",
- "promise-inflight": "^1.0.1",
- "rimraf": "^3.0.2",
- "ssri": "^9.0.0",
- "tar": "^6.1.11",
- "unique-filename": "^2.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/cacache/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/cacache/node_modules/lru-cache": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
- "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/cacache/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/cacache/node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/cacache/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/cacache/node_modules/rimraf/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/cacheable-lookup": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
@@ -11287,7 +10808,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
- "devOptional": true,
"license": "ISC",
"engines": {
"node": ">=10"
@@ -11307,14 +10827,12 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
"integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==",
- "dev": true,
"license": "MIT"
},
"node_modules/ci-info": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -11366,16 +10884,6 @@
"node": ">= 10.0"
}
},
- "node_modules/clean-stack": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/cli": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
@@ -11389,32 +10897,6 @@
"node": ">=0.2.5"
}
},
- "node_modules/cli-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
- "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "restore-cursor": "^3.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cli-spinners": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
- "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/cli-truncate": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
@@ -11495,16 +10977,6 @@
"node": ">=12"
}
},
- "node_modules/clone": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
- "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8"
- }
- },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -11519,6 +10991,31 @@
"node": ">=6"
}
},
+ "node_modules/clone-regexp": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz",
+ "integrity": "sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==",
+ "dependencies": {
+ "is-regexp": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/clone-regexp/node_modules/is-regexp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz",
+ "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
@@ -11602,8 +11099,8 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "devOptional": true,
"license": "ISC",
+ "optional": true,
"bin": {
"color-support": "bin.js"
}
@@ -11645,7 +11142,6 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -11661,7 +11157,6 @@
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
"integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -11838,78 +11333,6 @@
"node": ">=10"
}
},
- "node_modules/config-file-ts": {
- "version": "0.2.8-rc1",
- "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz",
- "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "glob": "^10.3.12",
- "typescript": "^5.4.3"
- }
- },
- "node_modules/config-file-ts/node_modules/glob": {
- "version": "10.4.5",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
- "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/config-file-ts/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/config-file-ts/node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/config-file-ts/node_modules/typescript": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
- "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
"node_modules/console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
@@ -11920,8 +11343,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
- "devOptional": true,
- "license": "ISC"
+ "license": "ISC",
+ "optional": true
},
"node_modules/constants-browserify": {
"version": "1.0.0",
@@ -11951,6 +11374,17 @@
"node": ">= 0.6"
}
},
+ "node_modules/convert-hrtime": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz",
+ "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/convert-source-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
@@ -12193,7 +11627,6 @@
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -12843,19 +12276,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/defaults": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
- "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "clone": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
@@ -12915,8 +12335,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==",
- "devOptional": true,
- "license": "MIT"
+ "license": "MIT",
+ "optional": true
},
"node_modules/depd": {
"version": "2.0.0",
@@ -12960,8 +12380,8 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
- "devOptional": true,
"license": "Apache-2.0",
+ "optional": true,
"engines": {
"node": ">=8"
}
@@ -13041,41 +12461,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/dir-compare": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz",
- "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "minimatch": "^3.0.5",
- "p-limit": "^3.1.0 "
- }
- },
- "node_modules/dir-compare/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/dir-compare/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -13083,39 +12468,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/dmg-builder": {
- "version": "25.1.8",
- "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-25.1.8.tgz",
- "integrity": "sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "app-builder-lib": "25.1.8",
- "builder-util": "25.1.7",
- "builder-util-runtime": "9.2.10",
- "fs-extra": "^10.1.0",
- "iconv-lite": "^0.6.2",
- "js-yaml": "^4.1.0"
- },
- "optionalDependencies": {
- "dmg-license": "^1.0.11"
- }
- },
- "node_modules/dmg-builder/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/dmg-license": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz",
@@ -13332,22 +12684,6 @@
"url": "https://dotenvx.com"
}
},
- "node_modules/dotenv-expand": {
- "version": "11.0.7",
- "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz",
- "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "dotenv": "^16.4.5"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
- }
- },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -13372,7 +12708,6 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
- "dev": true,
"license": "MIT"
},
"node_modules/ecc-jsbn": {
@@ -13410,7 +12745,6 @@
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"jake": "^10.8.5"
@@ -13423,15 +12757,15 @@
}
},
"node_modules/electron": {
- "version": "33.2.1",
- "resolved": "https://registry.npmjs.org/electron/-/electron-33.2.1.tgz",
- "integrity": "sha512-SG/nmSsK9Qg1p6wAW+ZfqU+AV8cmXMTIklUL18NnOKfZLlum4ZsDoVdmmmlL39ZmeCaq27dr7CgslRPahfoVJg==",
+ "version": "37.2.6",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-37.2.6.tgz",
+ "integrity": "sha512-Ns6xyxE+hIK5UlujtRlw7w4e2Ju/ImCWXf1Q/PoOhc0N3/6SN6YW7+ujCarsHbxWnolbW+1RlkHtdklUJpjbPA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@electron/get": "^2.0.0",
- "@types/node": "^20.9.0",
+ "@types/node": "^22.7.7",
"extract-zip": "^2.0.1"
},
"bin": {
@@ -13441,64 +12775,6 @@
"node": ">= 12.20.55"
}
},
- "node_modules/electron-builder": {
- "version": "25.1.8",
- "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-25.1.8.tgz",
- "integrity": "sha512-poRgAtUHHOnlzZnc9PK4nzG53xh74wj2Jy7jkTrqZ0MWPoHGh1M2+C//hGeYdA+4K8w4yiVCNYoLXF7ySj2Wig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "app-builder-lib": "25.1.8",
- "builder-util": "25.1.7",
- "builder-util-runtime": "9.2.10",
- "chalk": "^4.1.2",
- "dmg-builder": "25.1.8",
- "fs-extra": "^10.1.0",
- "is-ci": "^3.0.0",
- "lazy-val": "^1.0.5",
- "simple-update-notifier": "2.0.0",
- "yargs": "^17.6.2"
- },
- "bin": {
- "electron-builder": "cli.js",
- "install-app-deps": "install-app-deps.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/electron-builder/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/electron-builder/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/electron-devtools-installer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-4.0.0.tgz",
@@ -13570,54 +12846,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
- "node_modules/electron-publish": {
- "version": "25.1.7",
- "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-25.1.7.tgz",
- "integrity": "sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/fs-extra": "^9.0.11",
- "builder-util": "25.1.7",
- "builder-util-runtime": "9.2.10",
- "chalk": "^4.1.2",
- "fs-extra": "^10.1.0",
- "lazy-val": "^1.0.5",
- "mime": "^2.5.2"
- }
- },
- "node_modules/electron-publish/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/electron-publish/node_modules/fs-extra": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
- "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/electron-store": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz",
@@ -13656,23 +12884,6 @@
"integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==",
"license": "MIT"
},
- "node_modules/electron/node_modules/@types/node": {
- "version": "20.17.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz",
- "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~6.19.2"
- }
- },
- "node_modules/electron/node_modules/undici-types": {
- "version": "6.19.8",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
- "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/elliptic": {
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
@@ -13696,15 +12907,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/emitter-component": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.2.tgz",
- "integrity": "sha512-QdXO3nXOzZB4pAjM0n6ZE+R9/+kPpECA/XSELIcc54NeYVnBqIk+4DFiBgK+8QbV3mdvTG6nedl7dTYgO+5wDw==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/emittery": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
@@ -13743,17 +12945,6 @@
"node": ">= 0.8"
}
},
- "node_modules/encoding": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
- "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "iconv-lite": "^0.6.2"
- }
- },
"node_modules/encoding-sniffer": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
@@ -13823,7 +13014,6 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
- "dev": true,
"license": "MIT"
},
"node_modules/error-ex": {
@@ -13910,6 +13100,21 @@
"node": ">= 0.4"
}
},
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
@@ -14056,9 +13261,9 @@
}
},
"node_modules/eslint-visitor-keys": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
- "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -14497,13 +13702,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
- "node_modules/exponential-backoff": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
- "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==",
- "dev": true,
- "license": "Apache-2.0"
- },
"node_modules/express": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz",
@@ -14849,9 +14047,9 @@
}
},
"node_modules/extract-zip/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -15071,7 +14269,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"minimatch": "^5.0.1"
@@ -15081,7 +14278,6 @@
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
- "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -15348,7 +14544,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
- "dev": true,
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.0",
@@ -15365,7 +14560,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
@@ -15384,13 +14578,15 @@
}
},
"node_modules/form-data": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
- "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
@@ -15518,7 +14714,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "devOptional": true,
"license": "ISC",
"dependencies": {
"minipass": "^3.0.0"
@@ -15556,6 +14751,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/function-timeout": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-0.1.1.tgz",
+ "integrity": "sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
@@ -15566,27 +14772,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gauge": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
- "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
- "deprecated": "This package is no longer supported.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "aproba": "^1.0.3 || ^2.0.0",
- "color-support": "^1.1.3",
- "console-control-strings": "^1.1.0",
- "has-unicode": "^2.0.1",
- "signal-exit": "^3.0.7",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "wide-align": "^1.1.5"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/generic-names": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-4.0.0.tgz",
@@ -15819,9 +15004,9 @@
}
},
"node_modules/global-agent/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"dev": true,
"license": "ISC",
"optional": true,
@@ -15872,6 +15057,12 @@
"csstype": "^3.0.10"
}
},
+ "node_modules/google-protobuf": {
+ "version": "3.21.4",
+ "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz",
+ "integrity": "sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==",
+ "license": "(BSD-3-Clause AND Apache-2.0)"
+ },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -15971,19 +15162,37 @@
}
},
"node_modules/graphql-request/node_modules/form-data": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.2.tgz",
- "integrity": "sha512-sJe+TQb2vIaIyO783qN6BlMYWMw3WBOHA1Ay2qxsnjuafEOQFJ2JakedOQirT6D5XPRxDvS7AHYyem9fTpb4LQ==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.4.tgz",
+ "integrity": "sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.35"
},
"engines": {
"node": ">= 6"
}
},
+ "node_modules/grpc-reflection-js": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/grpc-reflection-js/-/grpc-reflection-js-0.3.0.tgz",
+ "integrity": "sha512-3lhTlQluPxVgbowCXA3tAZC3RJW+GSOUkguLNYl1QffYRiutUB3RDfPkQFTcrCFJgNiIIxx+iJkr8s3uSp3zWA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/google-protobuf": "^3.7.2",
+ "@types/lodash.set": "^4.3.6",
+ "google-protobuf": "^3.12.2",
+ "lodash.set": "^4.3.2",
+ "protobufjs": "^7.2.2"
+ },
+ "peerDependencies": {
+ "@grpc/grpc-js": "^1.0.0"
+ }
+ },
"node_modules/har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
@@ -16086,7 +15295,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
@@ -16102,8 +15310,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
- "devOptional": true,
- "license": "ISC"
+ "license": "ISC",
+ "optional": true
},
"node_modules/hash-base": {
"version": "3.0.5",
@@ -16183,7 +15391,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
"integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"lru-cache": "^6.0.0"
@@ -16196,7 +15403,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
@@ -16209,7 +15415,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true,
"license": "ISC"
},
"node_modules/html-encoding-sniffer": {
@@ -16598,16 +15803,6 @@
"node": ">=10.17.0"
}
},
- "node_modules/humanize-ms": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
- "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.0.0"
- }
- },
"node_modules/i18next": {
"version": "24.1.2",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-24.1.2.tgz",
@@ -16839,13 +16034,6 @@
"node": ">=8"
}
},
- "node_modules/infer-owner": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
- "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -16901,6 +16089,17 @@
"node": ">= 12"
}
},
+ "node_modules/ip-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz",
+ "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -17013,7 +16212,6 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
"integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ci-info": "^3.2.0"
@@ -17111,16 +16309,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-interactive": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
- "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-invalid-path": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz",
@@ -17154,12 +16342,20 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-lambda": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
- "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
- "dev": true,
- "license": "MIT"
+ "node_modules/is-ip": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz",
+ "integrity": "sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==",
+ "dependencies": {
+ "ip-regex": "^5.0.0",
+ "super-regex": "^0.2.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/is-map": {
"version": "2.0.3",
@@ -17405,19 +16601,6 @@
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
"license": "MIT"
},
- "node_modules/is-unicode-supported": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
- "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-valid-path": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz",
@@ -17470,7 +16653,6 @@
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz",
"integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 18.0.0"
@@ -17483,7 +16665,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
"license": "ISC"
},
"node_modules/isobject": {
@@ -17614,7 +16795,6 @@
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
- "dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@@ -17630,7 +16810,6 @@
"version": "10.9.2",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
"integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
- "dev": true,
"license": "Apache-2.0",
"dependencies": {
"async": "^3.2.3",
@@ -17649,7 +16828,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -17660,7 +16838,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -17677,7 +16854,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -19318,7 +18494,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
- "dev": true,
"license": "MIT"
},
"node_modules/leven": {
@@ -19440,7 +18615,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/lodash.curry": {
@@ -19518,6 +18692,12 @@
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT"
},
+ "node_modules/lodash.set": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
+ "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==",
+ "license": "MIT"
+ },
"node_modules/lodash.uniq": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@@ -19525,39 +18705,11 @@
"dev": true,
"license": "MIT"
},
- "node_modules/log-symbols": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
- "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.1.0",
- "is-unicode-supported": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/log-symbols/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0"
},
"node_modules/loose-envify": {
"version": "1.4.0",
@@ -19686,126 +18838,6 @@
"url": "https://github.com/wojtekmaj/make-event-props?sponsor=1"
}
},
- "node_modules/make-fetch-happen": {
- "version": "10.2.1",
- "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
- "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "agentkeepalive": "^4.2.1",
- "cacache": "^16.1.0",
- "http-cache-semantics": "^4.1.0",
- "http-proxy-agent": "^5.0.0",
- "https-proxy-agent": "^5.0.0",
- "is-lambda": "^1.0.1",
- "lru-cache": "^7.7.1",
- "minipass": "^3.1.6",
- "minipass-collect": "^1.0.2",
- "minipass-fetch": "^2.0.3",
- "minipass-flush": "^1.0.5",
- "minipass-pipeline": "^1.2.4",
- "negotiator": "^0.6.3",
- "promise-retry": "^2.0.1",
- "socks-proxy-agent": "^7.0.0",
- "ssri": "^9.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/make-fetch-happen/node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/make-fetch-happen/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
- "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@tootallnate/once": "2",
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/make-fetch-happen/node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/make-fetch-happen/node_modules/lru-cache": {
- "version": "7.18.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
- "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/make-fetch-happen/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/make-fetch-happen/node_modules/socks-proxy-agent": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
- "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "^6.0.2",
- "debug": "^4.3.3",
- "socks": "^2.6.2"
- },
- "engines": {
- "node": ">= 10"
- }
- },
"node_modules/makeerror": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@@ -20125,7 +19157,6 @@
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
- "dev": true,
"license": "MIT",
"bin": {
"mime": "cli.js"
@@ -20280,7 +19311,6 @@
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "devOptional": true,
"license": "ISC",
"dependencies": {
"yallist": "^4.0.0"
@@ -20289,88 +19319,16 @@
"node": ">=8"
}
},
- "node_modules/minipass-collect": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
- "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minipass-fetch": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
- "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "minipass": "^3.1.6",
- "minipass-sized": "^1.0.3",
- "minizlib": "^2.1.2"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- },
- "optionalDependencies": {
- "encoding": "^0.1.13"
- }
- },
- "node_modules/minipass-flush": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
- "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minipass-pipeline": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
- "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minipass-sized": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
- "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/minipass/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "devOptional": true,
"license": "ISC"
},
"node_modules/minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"minipass": "^3.0.0",
@@ -20384,7 +19342,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "devOptional": true,
"license": "ISC"
},
"node_modules/mkdirp": {
@@ -20546,32 +19503,6 @@
"tslib": "^2.0.3"
}
},
- "node_modules/node-abi": {
- "version": "3.71.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz",
- "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/node-abi/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/node-addon-api": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
@@ -20579,29 +19510,6 @@
"license": "MIT",
"optional": true
},
- "node_modules/node-api-version": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz",
- "integrity": "sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.3.5"
- }
- },
- "node_modules/node-api-version/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -20622,32 +19530,6 @@
}
}
},
- "node_modules/node-gyp": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz",
- "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "env-paths": "^2.2.0",
- "exponential-backoff": "^3.1.1",
- "glob": "^7.1.4",
- "graceful-fs": "^4.2.6",
- "make-fetch-happen": "^10.0.3",
- "nopt": "^6.0.0",
- "npmlog": "^6.0.0",
- "rimraf": "^3.0.2",
- "semver": "^7.3.5",
- "tar": "^6.1.2",
- "which": "^2.0.2"
- },
- "bin": {
- "node-gyp": "bin/node-gyp.js"
- },
- "engines": {
- "node": "^12.13 || ^14.13 || >=16"
- }
- },
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
@@ -20659,82 +19541,6 @@
"node-gyp-build-test": "build-test.js"
}
},
- "node_modules/node-gyp/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/node-gyp/node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "deprecated": "Glob versions prior to v9 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/node-gyp/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/node-gyp/node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/node-gyp/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/node-int64": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -20792,22 +19598,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
- "node_modules/nopt": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
- "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "abbrev": "^1.0.0"
- },
- "bin": {
- "nopt": "bin/nopt.js"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -20853,23 +19643,6 @@
"node": ">=8"
}
},
- "node_modules/npmlog": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
- "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
- "deprecated": "This package is no longer supported.",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "are-we-there-yet": "^3.0.0",
- "console-control-strings": "^1.1.0",
- "gauge": "^4.0.3",
- "set-blocking": "^2.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -21055,47 +19828,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/ora": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
- "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bl": "^4.1.0",
- "chalk": "^4.1.0",
- "cli-cursor": "^3.1.0",
- "cli-spinners": "^2.5.0",
- "is-interactive": "^1.0.0",
- "is-unicode-supported": "^0.1.0",
- "log-symbols": "^4.1.0",
- "strip-ansi": "^6.0.0",
- "wcwidth": "^1.0.1"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ora/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
"node_modules/os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
@@ -21168,22 +19900,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/p-map": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
- "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "aggregate-error": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/p-queue": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
@@ -21227,7 +19943,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
- "dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/pako": {
@@ -21463,7 +20178,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -21480,7 +20194,6 @@
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
- "dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
@@ -21497,14 +20210,12 @@
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true,
"license": "ISC"
},
"node_modules/path-scurry/node_modules/minipass": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "dev": true,
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -21596,21 +20307,6 @@
"path2d": "^0.2.0"
}
},
- "node_modules/pe-library": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz",
- "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/jet2jet"
- }
- },
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -21817,7 +20513,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz",
"integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"@xmldom/xmldom": "^0.8.8",
@@ -22838,18 +21533,10 @@
"asap": "~2.0.3"
}
},
- "node_modules/promise-inflight": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
- "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
- "dev": true,
- "license": "ISC"
- },
"node_modules/promise-retry": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"err-code": "^2.0.2",
@@ -22900,6 +21587,30 @@
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
"license": "MIT"
},
+ "node_modules/protobufjs": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
+ "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -23558,44 +22269,6 @@
"react-dom": ">=16.14.0"
}
},
- "node_modules/read-binary-file-arch": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz",
- "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4"
- },
- "bin": {
- "read-binary-file-arch": "cli.js"
- }
- },
- "node_modules/read-binary-file-arch/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/read-binary-file-arch/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -23616,6 +22289,105 @@
"node": ">=0.10.0"
}
},
+ "node_modules/read-config-file": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz",
+ "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "config-file-ts": "^0.2.4",
+ "dotenv": "^9.0.2",
+ "dotenv-expand": "^5.1.0",
+ "js-yaml": "^4.1.0",
+ "json5": "^2.2.0",
+ "lazy-val": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/read-config-file/node_modules/config-file-ts": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.6.tgz",
+ "integrity": "sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==",
+ "license": "MIT",
+ "dependencies": {
+ "glob": "^10.3.10",
+ "typescript": "^5.3.3"
+ }
+ },
+ "node_modules/read-config-file/node_modules/dotenv": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz",
+ "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/read-config-file/node_modules/dotenv-expand": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
+ "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/read-config-file/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/read-config-file/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/read-config-file/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/read-config-file/node_modules/typescript": {
+ "version": "5.9.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
+ "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
"node_modules/readable-stream": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.6.0.tgz",
@@ -23983,24 +22755,6 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"license": "MIT"
},
- "node_modules/resedit": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz",
- "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pe-library": "^0.4.1"
- },
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/jet2jet"
- }
- },
"node_modules/reselect": {
"version": "4.1.8",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
@@ -24090,25 +22844,10 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/restore-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
- "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
@@ -24541,7 +23280,6 @@
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
- "dev": true,
"license": "WTFPL OR ISC",
"dependencies": {
"truncate-utf8-bytes": "^1.0.0"
@@ -25192,8 +23930,8 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
- "devOptional": true,
- "license": "ISC"
+ "license": "ISC",
+ "optional": true
},
"node_modules/set-function-length": {
"version": "1.2.2",
@@ -25295,7 +24033,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
@@ -25308,7 +24045,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -25469,7 +24205,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
"integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"semver": "^7.5.3"
@@ -25482,7 +24217,6 @@
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -25676,19 +24410,6 @@
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
"license": "MIT"
},
- "node_modules/ssri": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
- "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minipass": "^3.1.1"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/stable": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
@@ -25731,7 +24452,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
"integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 6"
@@ -25760,16 +24480,6 @@
"node": ">= 0.4"
}
},
- "node_modules/stream": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz",
- "integrity": "sha512-gCq3NDI2P35B2n6t76YJuOp7d6cN/C7Rt0577l91wllh0sY9ZBuw9KaSGqH/b0hzn3CWWJbpbW0W0WvQ1H/Q7g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emitter-component": "^1.1.1"
- }
- },
"node_modules/stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
@@ -25916,7 +24626,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@@ -25967,7 +24676,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@@ -26252,9 +24960,9 @@
}
},
"node_modules/sumchecker/node_modules/debug": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
- "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -26276,6 +24984,22 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/super-regex": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz",
+ "integrity": "sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==",
+ "dependencies": {
+ "clone-regexp": "^3.0.0",
+ "function-timeout": "^0.1.0",
+ "time-span": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -26513,7 +25237,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
- "devOptional": true,
"license": "ISC",
"dependencies": {
"chownr": "^2.0.0",
@@ -26531,7 +25254,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
- "devOptional": true,
"license": "ISC",
"engines": {
"node": ">=8"
@@ -26541,7 +25263,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "devOptional": true,
"license": "MIT",
"bin": {
"mkdirp": "bin/cmd.js"
@@ -26554,14 +25275,12 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "devOptional": true,
"license": "ISC"
},
"node_modules/temp-file": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz",
"integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"async-exit-hook": "^2.0.1",
@@ -26572,7 +25291,6 @@
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
@@ -26808,6 +25526,20 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"license": "MIT"
},
+ "node_modules/time-span": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz",
+ "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==",
+ "dependencies": {
+ "convert-hrtime": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/timers-browserify": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -26842,6 +25574,22 @@
"@popperjs/core": "^2.9.0"
}
},
+ "node_modules/tldts": {
+ "version": "7.0.12",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.12.tgz",
+ "integrity": "sha512-M9ZQBPp6FyqhMcl233vHYyYRkxXOA1SKGlnq13S0mJdUhRSwr2w6I8rlchPL73wBwRlyIZpFvpu2VcdSMWLYXw==",
+ "dependencies": {
+ "tldts-core": "^7.0.12"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "7.0.12",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.12.tgz",
+ "integrity": "sha512-3K76aXywJFduGRsOYoY5JzINLs/WMlOkeDwPL+8OCPq2Rh39gkSDtWAxdJQlWjpun/xF/LHf29yqCi6VC/rHDA=="
+ },
"node_modules/tmp": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
@@ -26855,7 +25603,6 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
"integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"tmp": "^0.2.0"
@@ -26905,6 +25652,7 @@
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"psl": "^1.1.33",
@@ -26920,6 +25668,7 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">= 4.0.0"
@@ -26945,12 +25694,24 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
"integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
- "dev": true,
"license": "WTFPL",
"dependencies": {
"utf8-byte-length": "^1.0.1"
}
},
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
"node_modules/ts-interface-checker": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@@ -27169,7 +25930,6 @@
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "devOptional": true,
"license": "MIT"
},
"node_modules/unicode-canonical-property-names-ecmascript": {
@@ -27216,32 +25976,6 @@
"node": ">=4"
}
},
- "node_modules/unique-filename": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
- "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "unique-slug": "^3.0.0"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
- "node_modules/unique-slug": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
- "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "imurmurhash": "^0.1.4"
- },
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
@@ -27443,7 +26177,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
"integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==",
- "dev": true,
"license": "(WTFPL OR MIT)"
},
"node_modules/util": {
@@ -27609,16 +26342,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/wcwidth": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
- "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "defaults": "^1.0.3"
- }
- },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -27790,7 +26513,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
@@ -27866,8 +26588,8 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
- "devOptional": true,
"license": "ISC",
+ "optional": true,
"dependencies": {
"string-width": "^1.0.2 || 2 || 3 || 4"
}
@@ -27911,7 +26633,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@@ -29922,6 +28643,7 @@
"@aws-sdk/credential-providers": "3.750.0",
"@usebruno/common": "0.1.0",
"@usebruno/converters": "^0.1.0",
+ "@usebruno/filestore": "^0.1.0",
"@usebruno/js": "0.12.0",
"@usebruno/lang": "0.12.0",
"@usebruno/requests": "^0.1.0",
@@ -29941,7 +28663,6 @@
"lodash": "^4.17.21",
"qs": "^6.11.0",
"socks-proxy-agent": "^8.0.2",
- "tough-cookie": "^4.1.3",
"xmlbuilder": "^15.1.1",
"yargs": "^17.6.2"
},
@@ -31015,6 +29736,7 @@
"@rollup/plugin-typescript": "^12.1.2",
"@types/jest": "^29.5.14",
"babel-jest": "^29.7.0",
+ "is-ip": "^5.0.1",
"moment": "^2.29.4",
"rollup": "3.29.5",
"rollup-plugin-dts": "^5.0.0",
@@ -31576,7 +30298,7 @@
"@web/rollup-plugin-copy": "^0.5.1",
"babel-jest": "^29.7.0",
"rimraf": "^5.0.7",
- "rollup": "3.2.5",
+ "rollup": "3.29.5",
"rollup-plugin-dts": "^5.0.0",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-terser": "^7.0.2",
@@ -31664,30 +30386,16 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "packages/bruno-converters/node_modules/rollup": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.2.5.tgz",
- "integrity": "sha512-/Ha7HhVVofduy+RKWOQJrxe4Qb3xyZo+chcpYiD8SoQa4AG7llhupUtyfKSSrdBM2mWJjhM8wZwmbY23NmlIYw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=14.18.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
"packages/bruno-electron": {
"name": "bruno",
"version": "2.0.0",
"dependencies": {
"@aws-sdk/credential-providers": "3.750.0",
+ "@grpc/grpc-js": "^1.13.2",
+ "@grpc/proto-loader": "^0.7.13",
"@usebruno/common": "0.1.0",
"@usebruno/converters": "^0.1.0",
+ "@usebruno/filestore": "^0.1.0",
"@usebruno/js": "0.12.0",
"@usebruno/lang": "0.12.0",
"@usebruno/node-machine-id": "^2.0.0",
@@ -31703,6 +30411,7 @@
"content-disposition": "^0.5.4",
"decomment": "^0.9.5",
"dotenv": "^16.0.3",
+ "electron-builder": "^24.13.3",
"electron-is-dev": "^2.0.0",
"electron-notarize": "^1.2.2",
"electron-store": "^8.1.0",
@@ -31720,13 +30429,12 @@
"nanoid": "3.3.8",
"qs": "^6.11.0",
"socks-proxy-agent": "^8.0.2",
- "tough-cookie": "^4.1.3",
+ "tough-cookie": "^6.0.0",
"uuid": "^9.0.0",
"yup": "^0.32.11"
},
"devDependencies": {
- "electron": "33.2.1",
- "electron-builder": "25.1.8",
+ "electron": "~37.2.6",
"electron-devtools-installer": "^4.0.0"
},
"optionalDependencies": {
@@ -32195,6 +30903,145 @@
}
}
},
+ "packages/bruno-electron/node_modules/@electron/notarize": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.2.1.tgz",
+ "integrity": "sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "fs-extra": "^9.0.1",
+ "promise-retry": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/notarize/node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/osx-sign": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.5.tgz",
+ "integrity": "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "compare-version": "^0.1.2",
+ "debug": "^4.3.4",
+ "fs-extra": "^10.0.0",
+ "isbinaryfile": "^4.0.8",
+ "minimist": "^1.2.6",
+ "plist": "^3.0.5"
+ },
+ "bin": {
+ "electron-osx-flat": "bin/electron-osx-flat.js",
+ "electron-osx-sign": "bin/electron-osx-sign.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/osx-sign/node_modules/isbinaryfile": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
+ "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/gjtorikian/"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/universal": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.5.1.tgz",
+ "integrity": "sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@electron/asar": "^3.2.1",
+ "@malept/cross-spawn-promise": "^1.1.0",
+ "debug": "^4.3.1",
+ "dir-compare": "^3.0.0",
+ "fs-extra": "^9.0.1",
+ "minimatch": "^3.0.4",
+ "plist": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/universal/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/universal/node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "packages/bruno-electron/node_modules/@electron/universal/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "packages/bruno-electron/node_modules/@malept/cross-spawn-promise": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
+ "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/malept"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
+ }
+ ],
+ "license": "Apache-2.0",
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"packages/bruno-electron/node_modules/@smithy/abort-controller": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.1.tgz",
@@ -32760,6 +31607,66 @@
"node": ">=18.0.0"
}
},
+ "packages/bruno-electron/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "packages/bruno-electron/node_modules/app-builder-bin": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz",
+ "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==",
+ "license": "MIT"
+ },
+ "packages/bruno-electron/node_modules/app-builder-lib": {
+ "version": "24.13.3",
+ "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.13.3.tgz",
+ "integrity": "sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig==",
+ "license": "MIT",
+ "dependencies": {
+ "@develar/schema-utils": "~2.6.5",
+ "@electron/notarize": "2.2.1",
+ "@electron/osx-sign": "1.0.5",
+ "@electron/universal": "1.5.1",
+ "@malept/flatpak-bundler": "^0.4.0",
+ "@types/fs-extra": "9.0.13",
+ "async-exit-hook": "^2.0.1",
+ "bluebird-lst": "^1.0.9",
+ "builder-util": "24.13.1",
+ "builder-util-runtime": "9.2.4",
+ "chromium-pickle-js": "^0.2.0",
+ "debug": "^4.3.4",
+ "ejs": "^3.1.8",
+ "electron-publish": "24.13.1",
+ "form-data": "^4.0.0",
+ "fs-extra": "^10.1.0",
+ "hosted-git-info": "^4.1.0",
+ "is-ci": "^3.0.0",
+ "isbinaryfile": "^5.0.0",
+ "js-yaml": "^4.1.0",
+ "lazy-val": "^1.0.5",
+ "minimatch": "^5.1.1",
+ "read-config-file": "6.3.2",
+ "sanitize-filename": "^1.6.3",
+ "semver": "^7.3.8",
+ "tar": "^6.1.12",
+ "temp-file": "^3.4.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "dmg-builder": "24.13.3",
+ "electron-builder-squirrel-windows": "24.13.3"
+ }
+ },
"packages/bruno-electron/node_modules/axios": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz",
@@ -32771,6 +31678,193 @@
"proxy-from-env": "^1.1.0"
}
},
+ "packages/bruno-electron/node_modules/builder-util": {
+ "version": "24.13.1",
+ "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.13.1.tgz",
+ "integrity": "sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.1.6",
+ "7zip-bin": "~5.2.0",
+ "app-builder-bin": "4.0.0",
+ "bluebird-lst": "^1.0.9",
+ "builder-util-runtime": "9.2.4",
+ "chalk": "^4.1.2",
+ "cross-spawn": "^7.0.3",
+ "debug": "^4.3.4",
+ "fs-extra": "^10.1.0",
+ "http-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^5.0.1",
+ "is-ci": "^3.0.0",
+ "js-yaml": "^4.1.0",
+ "source-map-support": "^0.5.19",
+ "stat-mode": "^1.0.0",
+ "temp-file": "^3.4.0"
+ }
+ },
+ "packages/bruno-electron/node_modules/builder-util-runtime": {
+ "version": "9.2.4",
+ "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.4.tgz",
+ "integrity": "sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4",
+ "sax": "^1.2.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "packages/bruno-electron/node_modules/builder-util/node_modules/http-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+ "license": "MIT",
+ "dependencies": {
+ "@tootallnate/once": "2",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "packages/bruno-electron/node_modules/builder-util/node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "packages/bruno-electron/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "packages/bruno-electron/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "packages/bruno-electron/node_modules/dir-compare": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz",
+ "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-equal": "^1.0.0",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "packages/bruno-electron/node_modules/dir-compare/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "packages/bruno-electron/node_modules/dir-compare/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "packages/bruno-electron/node_modules/dmg-builder": {
+ "version": "24.13.3",
+ "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.13.3.tgz",
+ "integrity": "sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==",
+ "license": "MIT",
+ "dependencies": {
+ "app-builder-lib": "24.13.3",
+ "builder-util": "24.13.1",
+ "builder-util-runtime": "9.2.4",
+ "fs-extra": "^10.1.0",
+ "iconv-lite": "^0.6.2",
+ "js-yaml": "^4.1.0"
+ },
+ "optionalDependencies": {
+ "dmg-license": "^1.0.11"
+ }
+ },
+ "packages/bruno-electron/node_modules/electron-builder": {
+ "version": "24.13.3",
+ "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.13.3.tgz",
+ "integrity": "sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg==",
+ "license": "MIT",
+ "dependencies": {
+ "app-builder-lib": "24.13.3",
+ "builder-util": "24.13.1",
+ "builder-util-runtime": "9.2.4",
+ "chalk": "^4.1.2",
+ "dmg-builder": "24.13.3",
+ "fs-extra": "^10.1.0",
+ "is-ci": "^3.0.0",
+ "lazy-val": "^1.0.5",
+ "read-config-file": "6.3.2",
+ "simple-update-notifier": "2.0.0",
+ "yargs": "^17.6.2"
+ },
+ "bin": {
+ "electron-builder": "cli.js",
+ "install-app-deps": "install-app-deps.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "packages/bruno-electron/node_modules/electron-publish": {
+ "version": "24.13.1",
+ "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.13.1.tgz",
+ "integrity": "sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/fs-extra": "^9.0.11",
+ "builder-util": "24.13.1",
+ "builder-util-runtime": "9.2.4",
+ "chalk": "^4.1.2",
+ "fs-extra": "^10.1.0",
+ "lazy-val": "^1.0.5",
+ "mime": "^2.5.2"
+ }
+ },
"packages/bruno-electron/node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
@@ -32785,6 +31879,24 @@
"node": ">=12"
}
},
+ "packages/bruno-electron/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "packages/bruno-electron/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
"packages/bruno-electron/node_modules/nanoid": {
"version": "3.3.8",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
@@ -32803,6 +31915,136 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
+ "packages/bruno-electron/node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "packages/bruno-electron/node_modules/tough-cookie": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
+ "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==",
+ "dependencies": {
+ "tldts": "^7.0.5"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "packages/bruno-filestore": {
+ "name": "@usebruno/filestore",
+ "version": "0.1.0",
+ "license": "MIT",
+ "dependencies": {
+ "@usebruno/lang": "0.12.0",
+ "lodash": "^4.17.21"
+ },
+ "devDependencies": {
+ "@babel/preset-env": "^7.22.0",
+ "@babel/preset-typescript": "^7.22.0",
+ "@rollup/plugin-commonjs": "^23.0.2",
+ "@rollup/plugin-node-resolve": "^15.0.1",
+ "@rollup/plugin-typescript": "^9.0.2",
+ "@types/jest": "^29.5.11",
+ "@types/lodash": "^4.14.191",
+ "@types/node": "^24.1.0",
+ "babel-jest": "^29.7.0",
+ "jest": "^29.2.0",
+ "rimraf": "^3.0.2",
+ "rollup": "3.29.5",
+ "rollup-plugin-dts": "^5.0.0",
+ "rollup-plugin-peer-deps-external": "^2.2.4",
+ "rollup-plugin-terser": "^7.0.2",
+ "typescript": "^4.8.4"
+ }
+ },
+ "packages/bruno-filestore/node_modules/@types/node": {
+ "version": "24.1.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
+ "integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.8.0"
+ }
+ },
+ "packages/bruno-filestore/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "packages/bruno-filestore/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "packages/bruno-filestore/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "packages/bruno-filestore/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "packages/bruno-filestore/node_modules/undici-types": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+ "dev": true,
+ "license": "MIT"
+ },
"packages/bruno-graphql-docs": {
"name": "@usebruno/graphql-docs",
"version": "0.1.0",
@@ -32887,9 +32129,7 @@
"@rollup/plugin-commonjs": "^23.0.2",
"@rollup/plugin-node-resolve": "^15.0.1",
"rollup": "3.29.5",
- "rollup-plugin-terser": "^7.0.2",
- "stream": "^0.0.2",
- "util": "^0.12.5"
+ "rollup-plugin-terser": "^7.0.2"
},
"peerDependencies": {
"@usebruno/vm2": "^3.9.13"
@@ -32955,17 +32195,26 @@
"version": "0.1.0",
"license": "MIT",
"dependencies": {
+ "@faker-js/faker": "^9.7.0",
+ "@grpc/grpc-js": "^1.13.3",
+ "@grpc/proto-loader": "^0.7.15",
"@types/qs": "^6.9.18",
- "axios": "^1.9.0"
+ "axios": "^1.9.0",
+ "grpc-reflection-js": "^0.3.0",
+ "is-ip": "^5.0.1",
+ "tough-cookie": "^6.0.0"
},
"devDependencies": {
"@babel/preset-env": "^7.22.0",
"@babel/preset-typescript": "^7.22.0",
+ "@rollup/plugin-alias": "^5.1.1",
"@rollup/plugin-commonjs": "^23.0.2",
+ "@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-typescript": "^9.0.2",
"@types/jest": "^29.5.11",
"babel-jest": "^29.7.0",
+ "builtin-modules": "^5.0.0",
"jest": "^29.2.0",
"rollup": "3.29.5",
"rollup-plugin-dts": "^5.0.0",
@@ -32974,6 +32223,22 @@
"typescript": "^4.8.4"
}
},
+ "packages/bruno-requests/node_modules/@faker-js/faker": {
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.9.0.tgz",
+ "integrity": "sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fakerjs"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=9.0.0"
+ }
+ },
"packages/bruno-requests/node_modules/axios": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
@@ -32985,6 +32250,17 @@
"proxy-from-env": "^1.1.0"
}
},
+ "packages/bruno-requests/node_modules/tough-cookie": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
+ "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==",
+ "dependencies": {
+ "tldts": "^7.0.5"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"packages/bruno-schema": {
"name": "@usebruno/schema",
"version": "0.7.0",
diff --git a/package.json b/package.json
index 55873fff4..fe8dafdc9 100644
--- a/package.json
+++ b/package.json
@@ -14,16 +14,19 @@
"packages/bruno-tests",
"packages/bruno-toml",
"packages/bruno-graphql-docs",
- "packages/bruno-requests"
+ "packages/bruno-requests",
+ "packages/bruno-filestore"
],
"homepage": "https://usebruno.com",
"devDependencies": {
"@faker-js/faker": "^7.6.0",
"@jest/globals": "^29.2.0",
"@playwright/test": "^1.51.1",
+ "@rollup/plugin-json": "^6.1.0",
"@types/jest": "^29.5.11",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.14.1",
+ "@typescript-eslint/parser": "^8.39.0",
"concurrently": "^8.2.2",
"eslint": "^9.26.0",
"fs-extra": "^11.1.1",
@@ -40,6 +43,7 @@
"setup": "node ./scripts/setup.js",
"watch:converters": "npm run watch --workspace=packages/bruno-converters",
"dev": "concurrently --kill-others \"npm run dev:web\" \"npm run dev:electron\"",
+ "watch": "npm run dev:watch",
"dev:watch": "node ./scripts/dev-hot-reload.js",
"dev:web": "npm run dev --workspace=packages/bruno-app",
"build:web": "npm run build --workspace=packages/bruno-app",
@@ -48,6 +52,7 @@
"dev:electron:debug": "npm run debug --workspace=packages/bruno-electron",
"build:bruno-common": "npm run build --workspace=packages/bruno-common",
"build:bruno-requests": "npm run build --workspace=packages/bruno-requests",
+ "build:bruno-filestore": "npm run build --workspace=packages/bruno-filestore",
"build:bruno-converters": "npm run build --workspace=packages/bruno-converters",
"build:bruno-query": "npm run build --workspace=packages/bruno-query",
"build:graphql-docs": "npm run build --workspace=packages/bruno-graphql-docs",
@@ -72,4 +77,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json
index 5e0f6a8ea..aac3dbab7 100644
--- a/packages/bruno-app/package.json
+++ b/packages/bruno-app/package.json
@@ -111,5 +111,10 @@
"tailwindcss": "^3.4.1",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1"
+ },
+ "overrides": {
+ "httpsnippet": {
+ "form-data": "4.0.4"
+ }
}
}
diff --git a/packages/bruno-app/rsbuild.config.mjs b/packages/bruno-app/rsbuild.config.mjs
index b9b84129c..f21f80666 100644
--- a/packages/bruno-app/rsbuild.config.mjs
+++ b/packages/bruno-app/rsbuild.config.mjs
@@ -18,21 +18,6 @@ export default defineConfig({
}
})
],
- dev: {
- watchFiles: {
- paths: [
- 'src/providers/**',
- 'src/utils/**',
- 'src/hooks/**',
- 'src/themes/**',
- 'src/selectors/**'
- ],
- options: {
- usePolling: false,
- interval: 1000,
- },
- },
- },
source: {
tsconfigPath: './jsconfig.json', // Specifies the path to the JavaScript/TypeScript configuration file,
exclude: [
diff --git a/packages/bruno-app/src/components/CodeEditor/index.js b/packages/bruno-app/src/components/CodeEditor/index.js
index a83535300..4a8f0591a 100644
--- a/packages/bruno-app/src/components/CodeEditor/index.js
+++ b/packages/bruno-app/src/components/CodeEditor/index.js
@@ -186,6 +186,8 @@ export default class CodeEditor extends React.Component {
if (editor) {
editor.setOption('lint', this.props.mode && editor.getValue().trim().length > 0 ? this.lintOptions : false);
editor.on('change', this._onEdit);
+ editor.on('scroll', this.onScroll);
+ editor.scrollTo(null, this.props.initialScroll);
this.addOverlay();
const getAllVariablesHandler = () => getAllVariables(this.props.collection, this.props.item);
@@ -230,12 +232,18 @@ export default class CodeEditor extends React.Component {
if (this.props.theme !== prevProps.theme && this.editor) {
this.editor.setOption('theme', this.props.theme === 'dark' ? 'monokai' : 'default');
}
+
+ if (this.props.initialScroll !== prevProps.initialScroll) {
+ this.editor.scrollTo(null, this.props.initialScroll);
+ }
+
this.ignoreChangeEvent = false;
}
componentWillUnmount() {
if (this.editor) {
this.editor.off('change', this._onEdit);
+ this.editor.off('scroll', this.onScroll);
this.editor = null;
}
@@ -271,6 +279,8 @@ export default class CodeEditor extends React.Component {
this.editor.setOption('mode', 'brunovariables');
};
+ onScroll = (event) => this.props.onScroll?.(event);
+
_onEdit = () => {
if (!this.ignoreChangeEvent && this.editor) {
this.editor.setOption('lint', this.editor.getValue().trim().length > 0 ? this.lintOptions : false);
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/AwsV4Auth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/AwsV4Auth/index.js
index 0f14a4dfa..12e35cfea 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/AwsV4Auth/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/AwsV4Auth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -12,6 +14,8 @@ const AwsV4Auth = ({ collection }) => {
const { storedTheme } = useTheme();
const awsv4Auth = get(collection, 'root.request.auth.awsv4', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(awsv4Auth?.secretAccessKey);
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
@@ -131,7 +135,7 @@ const AwsV4Auth = ({ collection }) => {
-
+
{
collection={collection}
isSecret={true}
/>
+ {showWarning && }
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/BasicAuth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/BasicAuth/index.js
index 9ea532646..d0cf9d722 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/BasicAuth/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/BasicAuth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -12,6 +14,8 @@ const BasicAuth = ({ collection }) => {
const { storedTheme } = useTheme();
const basicAuth = get(collection, 'root.request.auth.basic', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(basicAuth?.password);
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
@@ -55,7 +59,7 @@ const BasicAuth = ({ collection }) => {
-
+
{
collection={collection}
isSecret={true}
/>
+ {showWarning && }
);
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/BearerAuth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/BearerAuth/index.js
index 82f8be12c..788182479 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/BearerAuth/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/BearerAuth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -12,6 +14,8 @@ const BearerAuth = ({ collection }) => {
const { storedTheme } = useTheme();
const bearerToken = get(collection, 'root.request.auth.bearer.token', '');
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(bearerToken);
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
@@ -30,7 +34,7 @@ const BearerAuth = ({ collection }) => {
return (
-
+
{
collection={collection}
isSecret={true}
/>
+ {showWarning && }
);
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js
index 582b17b82..22981f56b 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -12,6 +14,8 @@ const DigestAuth = ({ collection }) => {
const { storedTheme } = useTheme();
const digestAuth = get(collection, 'root.request.auth.digest', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(digestAuth?.password);
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
@@ -55,7 +59,7 @@ const DigestAuth = ({ collection }) => {
-
+
{
collection={collection}
isSecret={true}
/>
+ {showWarning && }
);
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/NTLMAuth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/NTLMAuth/index.js
index 173c99a12..38a9c18f0 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/NTLMAuth/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/NTLMAuth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -18,6 +20,8 @@ const NTLMAuth = ({ collection }) => {
const { storedTheme } = useTheme();
const ntlmAuth = get(collection, 'root.request.auth.ntlm', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(ntlmAuth?.password);
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
@@ -82,7 +86,7 @@ const NTLMAuth = ({ collection }) => {
-
+
{
collection={collection}
isSecret={true}
/>
+ {showWarning && }
diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/WsseAuth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/WsseAuth/index.js
index 2e1a2c65c..226cedd7b 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Auth/WsseAuth/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Auth/WsseAuth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -12,6 +14,8 @@ const WsseAuth = ({ collection }) => {
const { storedTheme } = useTheme();
const wsseAuth = get(collection, 'root.request.auth.wsse', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(wsseAuth?.password);
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
@@ -55,14 +59,16 @@ const WsseAuth = ({ collection }) => {
-
+
handlePasswordChange(val)}
collection={collection}
+ isSecret={true}
/>
+ {showWarning && }
);
diff --git a/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/StyledWrapper.js b/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/StyledWrapper.js
index 621b2b86b..affe1f7db 100644
--- a/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/StyledWrapper.js
+++ b/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/StyledWrapper.js
@@ -38,6 +38,48 @@ const StyledWrapper = styled.div`
outline: none !important;
}
}
+
+ .protocol-placeholder {
+ height: 100%;
+ position: relative;
+ display: inline-block;
+ width: 60px;
+ overflow: hidden;
+ }
+
+ .protocol-https,
+ .protocol-grpcs {
+ position: absolute;
+ right: 8px;
+ top: 0;
+ bottom: 0;
+ transition: transform 0.3s ease-in-out;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .protocol-https {
+ animation: slideUpDown 6s infinite;
+ transform: translateY(0);
+ }
+
+ .protocol-grpcs {
+ animation: slideUpDown 6s infinite 3s;
+ transform: translateY(100%);
+ }
+
+ @keyframes slideUpDown {
+ 0%, 45% {
+ transform: translateY(0);
+ }
+ 50%, 95% {
+ transform: translateY(100%);
+ }
+ 100% {
+ transform: translateY(0);
+ }
+ }
`;
export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/index.js b/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/index.js
index 7ae9ac85e..3f62fc23e 100644
--- a/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/ClientCertSettings/index.js
@@ -132,7 +132,10 @@ const ClientCertSettings = ({ root, clientCertConfig, onUpdate, onRemove }) => {
- https://
+
+ https://
+ grpcs://
+
{
}
return (
-
+
diff --git a/packages/bruno-app/src/components/CollectionSettings/Grpc/StyledWrapper.js b/packages/bruno-app/src/components/CollectionSettings/Grpc/StyledWrapper.js
new file mode 100644
index 000000000..21adc36e1
--- /dev/null
+++ b/packages/bruno-app/src/components/CollectionSettings/Grpc/StyledWrapper.js
@@ -0,0 +1,13 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ .available-certificates {
+ background-color: ${(props) => props.theme.requestTabPanel.url.bg};
+
+ button.remove-certificate {
+ color: ${(props) => props.theme.colors.text.danger};
+ }
+ }
+`;
+
+export default StyledWrapper;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/CollectionSettings/Grpc/index.js b/packages/bruno-app/src/components/CollectionSettings/Grpc/index.js
new file mode 100644
index 000000000..db2313efd
--- /dev/null
+++ b/packages/bruno-app/src/components/CollectionSettings/Grpc/index.js
@@ -0,0 +1,263 @@
+import React, { useState, useRef, useEffect } from 'react';
+import { useFormik } from 'formik';
+import { useDispatch } from 'react-redux';
+import StyledWrapper from './StyledWrapper';
+import toast from 'react-hot-toast';
+import { updateBrunoConfig } from 'providers/ReduxStore/slices/collections/actions';
+import cloneDeep from 'lodash/cloneDeep';
+import { IconTrash, IconFile, IconFileImport, IconAlertCircle } from '@tabler/icons';
+import { getRelativePath, getBasename, getDirPath } from 'utils/common/path';
+import { Tooltip } from 'react-tooltip';
+import { existsSync, resolvePath } from '../../../utils/filesystem';
+
+const GrpcSettings = ({ collection }) => {
+ const dispatch = useDispatch();
+ const {
+ brunoConfig: { grpc: grpcConfig = {} }
+ } = collection;
+
+ const fileInputRef = useRef(null);
+ const [protoFileValidity, setProtoFileValidity] = useState({});
+
+ const formik = useFormik({
+ enableReinitialize: true,
+ initialValues: {
+ protoFiles: grpcConfig.protoFiles || []
+ },
+ onSubmit: (newGrpcConfig) => {
+ const brunoConfig = cloneDeep(collection.brunoConfig);
+ brunoConfig.grpc = newGrpcConfig;
+ dispatch(updateBrunoConfig(brunoConfig, collection.uid));
+ toast.success('gRPC settings updated');
+ }
+ });
+
+ // Get file path using the ipcRenderer
+ const getProtoFile = (event) => {
+ const files = event?.files;
+ if (files && files.length > 0) {
+ const newProtoFiles = [...formik.values.protoFiles];
+
+ for (let i = 0; i < files.length; i++) {
+ const filePath = window?.ipcRenderer?.getFilePath(files[i]);
+ if (filePath) {
+ const relativePath = getRelativePath(filePath, collection.pathname);
+ const protoFileObj = {
+ path: relativePath,
+ type: 'file'
+ };
+
+ // Check if this path already exists
+ const exists = newProtoFiles.some(pf => pf.path === protoFileObj.path);
+ if (!exists) {
+ newProtoFiles.push(protoFileObj);
+ }
+ }
+ }
+
+ formik.setFieldValue('protoFiles', newProtoFiles);
+ // Reset the file input
+ if (fileInputRef.current) {
+ fileInputRef.current.value = '';
+ }
+ }
+ };
+
+ // Handler for removing a proto file
+ const handleRemoveProtoFile = (index) => {
+ const updatedProtoFiles = [...formik.values.protoFiles];
+ updatedProtoFiles.splice(index, 1);
+ formik.setFieldValue('protoFiles', updatedProtoFiles);
+ };
+
+ // Handle the browse button click
+ const handleBrowseClick = () => {
+ if (fileInputRef.current) {
+ fileInputRef.current.click();
+ }
+ };
+
+ // Check if a proto file path is valid
+ const isProtoFileValid = async (protoFile) => {
+ try {
+ const absolutePath = await resolvePath(protoFile.path, collection.pathname);
+ return await existsSync(absolutePath);
+ } catch (error) {
+ return false;
+ }
+ };
+
+ // Validate all proto files and update state
+ useEffect(() => {
+ const validateProtoFiles = async () => {
+ const validityMap = {};
+ for (const file of formik.values.protoFiles) {
+ validityMap[file.path] = await isProtoFileValid(file);
+ }
+ setProtoFileValidity(validityMap);
+ };
+
+ validateProtoFiles();
+ }, [formik.values.protoFiles, collection.pathname]);
+
+ // Handle replacing an invalid proto file
+ const handleReplaceProtoFile = (index) => {
+ if (fileInputRef.current) {
+ fileInputRef.current.click();
+ // Store the index to replace after file selection
+ fileInputRef.current.dataset.replaceIndex = index;
+ }
+ };
+
+ // Handle file input change
+ const handleFileInputChange = (e) => {
+ const replaceIndex = e.target.dataset.replaceIndex;
+ if (replaceIndex !== undefined) {
+ // Handle replacement
+ const files = e.target.files;
+ if (files && files.length > 0) {
+ const filePath = window?.ipcRenderer?.getFilePath(files[0]);
+ if (filePath) {
+ const relativePath = getRelativePath(filePath, collection.pathname);
+ const updatedProtoFiles = [...formik.values.protoFiles];
+ updatedProtoFiles[replaceIndex] = {
+ path: relativePath,
+ type: 'file'
+ };
+ formik.setFieldValue('protoFiles', updatedProtoFiles);
+ }
+ }
+ delete e.target.dataset.replaceIndex;
+ } else {
+ getProtoFile(e.target);
+ }
+ };
+
+ return (
+
+
+
+ );
+};
+
+export default GrpcSettings;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/CollectionSettings/Headers/index.js b/packages/bruno-app/src/components/CollectionSettings/Headers/index.js
index 9ae6e1e07..d0968c425 100644
--- a/packages/bruno-app/src/components/CollectionSettings/Headers/index.js
+++ b/packages/bruno-app/src/components/CollectionSettings/Headers/index.js
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useState } from 'react';
import get from 'lodash/get';
import cloneDeep from 'lodash/cloneDeep';
import { IconTrash } from '@tabler/icons';
@@ -7,19 +7,30 @@ import { useTheme } from 'providers/Theme';
import {
addCollectionHeader,
updateCollectionHeader,
- deleteCollectionHeader
+ deleteCollectionHeader,
+ setCollectionHeaders
} from 'providers/ReduxStore/slices/collections';
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
import SingleLineEditor from 'components/SingleLineEditor';
import StyledWrapper from './StyledWrapper';
import { headers as StandardHTTPHeaders } from 'know-your-http-well';
import { MimeTypes } from 'utils/codemirror/autocompleteConstants';
+import BulkEditor from 'components/BulkEditor/index';
const headerAutoCompleteList = StandardHTTPHeaders.map((e) => e.header);
const Headers = ({ collection }) => {
const dispatch = useDispatch();
const { storedTheme } = useTheme();
const headers = get(collection, 'root.request.headers', []);
+ const [isBulkEditMode, setIsBulkEditMode] = useState(false);
+
+ const toggleBulkEditMode = () => {
+ setIsBulkEditMode(!isBulkEditMode);
+ };
+
+ const handleBulkHeadersChange = (newHeaders) => {
+ dispatch(setCollectionHeaders({ collectionUid: collection.uid, headers: newHeaders }));
+ };
const addHeader = () => {
dispatch(
@@ -63,6 +74,22 @@ const Headers = ({ collection }) => {
);
};
+ if (isBulkEditMode) {
+ return (
+
+
+ Add request headers that will be sent with every request in this collection.
+
+
+
+ );
+ }
+
return (
@@ -141,9 +168,14 @@ const Headers = ({ collection }) => {
: null}
-
+
+
+
+
@@ -74,7 +98,7 @@ const PresetsSettings = ({ collection }) => {
id="request-url"
type="text"
name="requestUrl"
- placeholder='Request URL'
+ placeholder="Request URL"
className="block textbox"
autoComplete="off"
autoCorrect="off"
@@ -87,6 +111,7 @@ const PresetsSettings = ({ collection }) => {
+
@@ -239,4 +239,4 @@ const RequestDetailsPanel = () => {
);
};
-export default RequestDetailsPanel;
\ No newline at end of file
+export default RequestDetailsPanel;
diff --git a/packages/bruno-app/src/components/Devtools/Console/index.js b/packages/bruno-app/src/components/Devtools/Console/index.js
index bde9a8b1d..e87e38d37 100644
--- a/packages/bruno-app/src/components/Devtools/Console/index.js
+++ b/packages/bruno-app/src/components/Devtools/Console/index.js
@@ -26,7 +26,7 @@ import {
} from 'providers/ReduxStore/slices/logs';
import NetworkTab from './NetworkTab';
import RequestDetailsPanel from './RequestDetailsPanel';
-import DebugTab from './DebugTab';
+// import DebugTab from './DebugTab';
import ErrorDetailsPanel from './ErrorDetailsPanel';
import StyledWrapper from './StyledWrapper';
@@ -40,8 +40,8 @@ const LogIcon = ({ type }) => {
return ;
case 'info':
return ;
- case 'debug':
- return ;
+ // case 'debug':
+ // return ;
default:
return ;
}
@@ -384,8 +384,8 @@ const Console = () => {
);
case 'network':
return ;
- case 'debug':
- return ;
+ // case 'debug':
+ // return ;
default:
return (
{
);
- case 'debug':
- return (
-
-
- {debugErrors.length > 0 && (
-
- )}
-
-
- );
+ // case 'debug':
+ // return (
+ //
+ //
+ // {debugErrors.length > 0 && (
+ //
+ // )}
+ //
+ //
+ // );
default:
return null;
}
@@ -484,13 +484,13 @@ const Console = () => {
Network
-
+ */}
diff --git a/packages/bruno-app/src/components/Dropdown/StyledWrapper.js b/packages/bruno-app/src/components/Dropdown/StyledWrapper.js
index f784cf527..3da7f2d34 100644
--- a/packages/bruno-app/src/components/Dropdown/StyledWrapper.js
+++ b/packages/bruno-app/src/components/Dropdown/StyledWrapper.js
@@ -16,6 +16,7 @@ const Wrapper = styled.div`
border-radius: 3px;
max-height: 90vh;
overflow-y: auto;
+ max-width: unset !important;
.tippy-content {
padding-left: 0;
diff --git a/packages/bruno-app/src/components/Dropdown/index.js b/packages/bruno-app/src/components/Dropdown/index.js
index 3deb0e849..c4eccce64 100644
--- a/packages/bruno-app/src/components/Dropdown/index.js
+++ b/packages/bruno-app/src/components/Dropdown/index.js
@@ -2,7 +2,7 @@ import React from 'react';
import Tippy from '@tippyjs/react';
import StyledWrapper from './StyledWrapper';
-const Dropdown = ({ icon, children, onCreate, placement, transparent }) => {
+const Dropdown = ({ icon, children, onCreate, placement, transparent, ...props }) => {
return (
{
interactive={true}
trigger="click"
appendTo="parent"
+ {...props}
>
{icon}
diff --git a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/constants.js b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/constants.js
new file mode 100644
index 000000000..c7dbe0ef5
--- /dev/null
+++ b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/constants.js
@@ -0,0 +1,11 @@
+const sensitiveFields = [
+ 'request.auth.oauth2.clientSecret',
+ 'request.auth.basic.password',
+ 'request.auth.digest.password',
+ 'request.auth.wsse.password',
+ 'request.auth.ntlm.password',
+ 'request.auth.awsv4.secretAccessKey',
+ 'request.auth.bearer.token'
+];
+
+export { sensitiveFields };
diff --git a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js
index c777aa85f..5ba3b0797 100644
--- a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js
+++ b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js
@@ -1,5 +1,6 @@
-import React, { useRef, useEffect } from 'react';
+import React, { useRef, useEffect, useMemo } from 'react';
import cloneDeep from 'lodash/cloneDeep';
+import { get } from 'lodash';
import { IconTrash, IconAlertCircle, IconDeviceFloppy, IconRefresh, IconCircleCheck } from '@tabler/icons';
import { useTheme } from 'providers/Theme';
import { useDispatch, useSelector } from 'react-redux';
@@ -13,7 +14,9 @@ import { variableNameRegex } from 'utils/common/regex';
import { saveEnvironment } from 'providers/ReduxStore/slices/collections/actions';
import toast from 'react-hot-toast';
import { Tooltip } from 'react-tooltip';
-import { getGlobalEnvironmentVariables } from 'utils/collections';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { getGlobalEnvironmentVariables, flattenItems, isItemARequest } from 'utils/collections';
+import { sensitiveFields } from './constants';
const EnvironmentVariables = ({ environment, collection, setIsModified, originalEnvironmentVariables, onClose }) => {
const dispatch = useDispatch();
@@ -26,6 +29,50 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
_collection.globalEnvironmentVariables = globalEnvironmentVariables;
+ const nonSecretSensitiveVarUsageMap = useMemo(() => {
+ const result = {};
+ if (!collection || !environment?.variables) {
+ return result;
+ }
+ const nonSecretVars = environment.variables.filter((v) => v.enabled && !v.secret && v.name);
+ if (!nonSecretVars.length) {
+ return result;
+ }
+ const varNames = new Set(nonSecretVars.map((v) => v.name));
+
+ const checkSensitiveField = (obj, fieldPath) => {
+ const value = get(obj, fieldPath);
+ if (typeof value === 'string') {
+ varNames.forEach((varName) => {
+ if (new RegExp(`\{\{\s*${varName}\s*\}\}`).test(value)) {
+ result[varName] = true;
+ }
+ });
+ }
+ };
+
+ const getObjectToProcess = (item) => {
+ if (isItemARequest(item)) {
+ return item.draft || item;
+ }
+ return item.root;
+ };
+
+ const collectionObj = getObjectToProcess(collection);
+ sensitiveFields.forEach((fieldPath) => {
+ checkSensitiveField(collectionObj, fieldPath);
+ });
+
+ const items = flattenItems(collection.items || []);
+ items.forEach((item) => {
+ const objToProcess = getObjectToProcess(item);
+ sensitiveFields.forEach((fieldPath) => {
+ checkSensitiveField(objToProcess, fieldPath);
+ });
+ });
+ return result;
+ }, [collection, environment]);
+
const formik = useFormik({
enableReinitialize: true,
initialValues: environment.variables || [],
@@ -61,6 +108,8 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
}
});
+ const hasSensitiveUsage = (name) => !!nonSecretSensitiveVarUsageMap[name];
+
// Effect to track modifications.
React.useEffect(() => {
setIsModified(formik.dirty);
@@ -163,7 +212,7 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
-
+ |
formik.setFieldValue(`${index}.value`, newValue, true)}
/>
+ {!variable.secret && hasSensitiveUsage(variable.name) && (
+
+ )}
|
e.header);
const Headers = ({ collection, folder }) => {
const dispatch = useDispatch();
const { storedTheme } = useTheme();
const headers = get(folder, 'root.request.headers', []);
+ const [isBulkEditMode, setIsBulkEditMode] = useState(false);
+
+ const toggleBulkEditMode = () => {
+ setIsBulkEditMode(!isBulkEditMode);
+ };
+
+ const handleBulkHeadersChange = (newHeaders) => {
+ dispatch(setFolderHeaders({ collectionUid: collection.uid, folderUid: folder.uid, headers: newHeaders }));
+ };
const addHeader = () => {
dispatch(
@@ -62,6 +72,22 @@ const Headers = ({ collection, folder }) => {
);
};
+ if (isBulkEditMode) {
+ return (
+
+
+ Request headers that will be sent with every request inside this folder.
+
+
+
+ );
+ }
+
return (
@@ -141,9 +167,14 @@ const Headers = ({ collection, folder }) => {
: null}
-
+
+
+
+
{inputsConfig.map((input) => {
const { key, label, isSecret } = input;
+ const value = oAuth[key] || '';
+ const { showWarning, warningMessage } = isSensitive(value);
+
return (
-
+
handleChange(key, val)}
@@ -110,6 +118,7 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu
item={item}
isSecret={isSecret}
/>
+ {isSecret && showWarning && }
);
@@ -284,7 +293,13 @@ const OAuth2ClientCredentials = ({ save, item = {}, request, handleRun, updateAu
-
+
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js
index 3952180b0..9715aa3ce 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Implicit/index.js
@@ -1,16 +1,15 @@
-import React, { useRef, forwardRef, useState, useMemo } from 'react';
+import React, { useRef, forwardRef, useMemo } from 'react';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
-import { IconCaretDown, IconLoader2, IconSettings, IconKey, IconHelp, IconAdjustmentsHorizontal } from '@tabler/icons';
+import { IconCaretDown, IconSettings, IconKey, IconHelp, IconAdjustmentsHorizontal } from '@tabler/icons';
import Dropdown from 'components/Dropdown';
import SingleLineEditor from 'components/SingleLineEditor';
-import { clearOauth2Cache, fetchOauth2Credentials } from 'providers/ReduxStore/slices/collections/actions';
import Wrapper from './StyledWrapper';
import { inputsConfig } from './inputsConfig';
-import toast from 'react-hot-toast';
import Oauth2TokenViewer from '../Oauth2TokenViewer/index';
-import { cloneDeep } from 'lodash';
+import Oauth2ActionButtons from '../Oauth2ActionButtons/index';
+import AdditionalParams from '../AdditionalParams/index';
import { getAllVariables } from 'utils/collections/index';
import { interpolate } from '@usebruno/common';
@@ -19,7 +18,6 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle
const { storedTheme } = useTheme();
const dropdownTippyRef = useRef();
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
- const [fetchingToken, toggleFetchingToken] = useState(false);
const oAuth = get(request, 'auth.oauth2', {});
const {
@@ -49,38 +47,6 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle
);
});
- const handleFetchOauth2Credentials = async () => {
- let requestCopy = cloneDeep(request);
- requestCopy.oauth2 = requestCopy?.auth.oauth2;
- requestCopy.headers = {};
- toggleFetchingToken(true);
- try {
- const result = await dispatch(fetchOauth2Credentials({
- itemUid: item.uid,
- request: requestCopy,
- collection,
- folderUid: folder?.uid || null,
- forceGetToken: true
- }));
-
- toggleFetchingToken(false);
-
- // Check if the result contains error or if access_token is missing
- if (result?.error || !result?.access_token) {
- const errorMessage = result?.error || 'No access token received from authorization server';
- toast.error(errorMessage);
- return;
- }
-
- toast.success('Token fetched successfully!');
- }
- catch (error) {
- console.error(error);
- toggleFetchingToken(false);
- toast.error(error?.message || 'An error occurred while fetching token!');
- }
- }
-
const handleSave = () => { save(); };
const handleChange = (key, value) => {
@@ -111,16 +77,6 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle
handleChange('autoFetchToken', e.target.checked);
};
- const handleClearCache = (e) => {
- dispatch(clearOauth2Cache({ collectionUid: collection?.uid, url: interpolatedAuthUrl, credentialsId }))
- .then(() => {
- toast.success('Cleared cache successfully');
- })
- .catch((err) => {
- toast.error(err.message);
- });
- };
-
return (
@@ -262,18 +218,14 @@ const OAuth2Implicit = ({ save, item = {}, request, handleRun, updateAuth, colle
-
-
- Get Access Token{fetchingToken ? : ""}
-
-
- Clear Cache
-
-
+
+
);
};
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js
index de729fdd5..3d3dc697d 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2ActionButtons/index.js
@@ -99,12 +99,22 @@ const Oauth2ActionButtons = ({ item, request, collection, url: accessTokenUrl, c
return (
-
+
Get Access Token{fetchingToken? : ""}
- {creds?.refresh_token ?
- Refresh Token{refreshingToken? : ""}
- : null}
+ {creds?.refresh_token ?
+
+ Refresh Token{refreshingToken? : ""}
+
+ : null}
Clear Cache
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js
index 385607848..f048183e6 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/index.js
@@ -1,4 +1,5 @@
import React, { useRef, forwardRef } from 'react';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -9,14 +10,16 @@ import { inputsConfig } from './inputsConfig';
import Dropdown from 'components/Dropdown';
import Oauth2TokenViewer from '../Oauth2TokenViewer/index';
import Oauth2ActionButtons from '../Oauth2ActionButtons/index';
+import AdditionalParams from '../AdditionalParams/index';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning/index';
const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, updateAuth, collection }) => {
const dispatch = useDispatch();
const { storedTheme } = useTheme();
const dropdownTippyRef = useRef();
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
-
const oAuth = get(request, 'auth.oauth2', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
const {
accessTokenUrl,
@@ -32,7 +35,8 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update
tokenQueryKey,
refreshTokenUrl,
autoRefreshToken,
- autoFetchToken
+ autoFetchToken,
+ additionalParameters
} = oAuth;
const refreshTokenUrlAvailable = refreshTokenUrl?.trim() !== '';
@@ -80,6 +84,7 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update
refreshTokenUrl,
autoRefreshToken,
autoFetchToken,
+ additionalParameters,
[key]: value
}
})
@@ -99,12 +104,15 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update
{inputsConfig.map((input) => {
const { key, label, isSecret } = input;
+ const value = oAuth[key] || '';
+ const { showWarning, warningMessage } = isSensitive(value);
+
return (
-
+
handleChange(key, val)}
@@ -113,6 +121,7 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update
item={item}
isSecret={isSecret}
/>
+ {isSecret && showWarning && }
);
@@ -287,6 +296,13 @@ const OAuth2PasswordCredentials = ({ save, item = {}, request, handleRun, update
+
);
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/WsseAuth/index.js b/packages/bruno-app/src/components/RequestPane/Auth/WsseAuth/index.js
index 05e9daaf1..fde2310c9 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/WsseAuth/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/WsseAuth/index.js
@@ -1,4 +1,6 @@
import React from 'react';
+import SensitiveFieldWarning from 'components/SensitiveFieldWarning';
+import { useDetectSensitiveField } from 'hooks/useDetectSensitiveField';
import get from 'lodash/get';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
@@ -12,6 +14,8 @@ const WsseAuth = ({ item, collection, updateAuth, request, save }) => {
const { storedTheme } = useTheme();
const wsseAuth = get(request, 'auth.wsse', {});
+ const { isSensitive } = useDetectSensitiveField(collection);
+ const { showWarning, warningMessage } = isSensitive(wsseAuth?.password);
const handleRun = () => dispatch(sendRequest(item, collection.uid));
@@ -63,7 +67,7 @@ const WsseAuth = ({ item, collection, updateAuth, request, save }) => {
-
+
{
item={item}
isSecret={true}
/>
+ {showWarning && }
);
diff --git a/packages/bruno-app/src/components/RequestPane/Auth/index.js b/packages/bruno-app/src/components/RequestPane/Auth/index.js
index c16f7bb68..7ccbc3e7d 100644
--- a/packages/bruno-app/src/components/RequestPane/Auth/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Auth/index.js
@@ -109,7 +109,7 @@ const Auth = ({ item, collection }) => {
};
return (
-
+
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcBody/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/GrpcBody/StyledWrapper.js
new file mode 100644
index 000000000..4b1ebcdb1
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcBody/StyledWrapper.js
@@ -0,0 +1,59 @@
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ flex: 1;
+ /* height: 100%; */
+ position: relative;
+
+ .grpc-message-header {
+ .font-medium {
+ color: ${(props) => props.theme.text};
+ }
+
+ button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+
+ &:hover {
+ transform: scale(1.1);
+ }
+
+ &:active {
+ transform: scale(0.95);
+ }
+ }
+ }
+
+ #grpc-messages-container {
+ /* height: 100%; */
+ position: relative;
+ }
+
+ .add-message-btn-container {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding-top: 8px;
+ background: ${(props) => props.theme.bg || '#fff'};
+ z-index: 15;
+ border-top: 1px solid ${(props) => props.theme.border || 'rgba(0, 0, 0, 0.1)'};
+
+ .add-message-btn {
+ width: 100%;
+ }
+ }
+
+ .CodeMirror {
+ border-top: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+`;
+
+export default Wrapper;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js b/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js
new file mode 100644
index 000000000..ce7cdebd9
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcBody/index.js
@@ -0,0 +1,354 @@
+import React, { useState, useEffect, useRef } from 'react';
+import { get } from 'lodash';
+import { useDispatch, useSelector } from 'react-redux';
+import { useTheme } from 'providers/Theme';
+import { updateRequestBody } from 'providers/ReduxStore/slices/collections';
+import { saveRequest } from 'providers/ReduxStore/slices/collections/actions';
+import { sendGrpcMessage, generateGrpcSampleMessage } from 'utils/network/index';
+import useLocalStorage from 'hooks/useLocalStorage';
+
+import CodeEditor from 'components/CodeEditor/index';
+import StyledWrapper from './StyledWrapper';
+import { IconSend, IconRefresh, IconWand, IconPlus, IconTrash, IconChevronDown, IconChevronUp } from '@tabler/icons';
+import ToolHint from 'components/ToolHint/index';
+import { toastError } from 'utils/common/error';
+import { format, applyEdits } from 'jsonc-parser';
+import toast from 'react-hot-toast'
+import { getAbsoluteFilePath } from 'utils/common/path';
+
+const SingleGrpcMessage = ({ message, item, collection, index, methodType, isCollapsed, onToggleCollapse, handleRun, canClientSendMultipleMessages }) => {
+ const dispatch = useDispatch();
+ const { displayedTheme, theme } = useTheme();
+ const preferences = useSelector((state) => state.app.preferences);
+ const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body');
+ const isConnectionActive = useSelector((state) => state.collections.activeConnections.includes(item.uid));
+
+ // Access gRPC method metadata from local storage
+ const [reflectionCache] = useLocalStorage('bruno.grpc.reflectionCache', {});
+ const [protofileCache] = useLocalStorage('bruno.grpc.protofileCache', {});
+
+ const canClientStream = methodType === 'client-streaming' || methodType === 'bidi-streaming';
+
+ const { name, content } = message;
+
+ const onEdit = (value) => {
+ const currentMessages = [...(body.grpc || [])];
+
+ currentMessages[index] = {
+ name: name ? name : `message ${index + 1}`,
+ content: value
+ };
+
+ dispatch(
+ updateRequestBody({
+ content: currentMessages,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ })
+ );
+ };
+
+ const onSend = async () => {
+ try {
+ await sendGrpcMessage(item, collection.uid, content);
+ } catch (error) {
+ console.error('Error sending message:', error);
+ }
+ }
+ const onSave = () => dispatch(saveRequest(item.uid, collection.uid));
+
+ const onRegenerateMessage = async () => {
+ try {
+ const methodPath = item.draft?.request?.method || item.request?.method;
+
+ if (!methodPath) {
+ toastError(new Error('Method path not found in request'));
+ return;
+ }
+
+ // Get the URL and protoPath to determine which cache to use
+ const url = item.draft?.request?.url || item.request?.url;
+ const protoPath = item.draft?.request?.protoPath || item.request?.protoPath;
+
+ // Find the method metadata from the appropriate cache
+ let methodMetadata = null;
+ if (protoPath) {
+ // Use protofile cache if protoPath is available
+ const absolutePath = getAbsoluteFilePath(protoPath, collection.pathname);
+ const cachedMethods = protofileCache[absolutePath];
+ if (cachedMethods) {
+ methodMetadata = cachedMethods.find(method => method.path === methodPath);
+ }
+ } else if (url) {
+ // Use reflection cache if no protoPath (reflection mode)
+ const cachedMethods = reflectionCache[url];
+ if (cachedMethods) {
+ methodMetadata = cachedMethods.find(method => method.path === methodPath);
+ }
+ }
+
+ const result = await generateGrpcSampleMessage(
+ methodPath,
+ content,
+ {
+ arraySize: 2,
+ methodMetadata // Pass the method metadata to the function
+ }
+ );
+
+ if (result.success) {
+ const currentMessages = [...(body.grpc || [])];
+
+ currentMessages[index] = {
+ name: name ? name : `message ${index + 1}`,
+ content: result.message
+ };
+
+ dispatch(
+ updateRequestBody({
+ content: currentMessages,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ })
+ );
+
+ toast.success('Sample message generated successfully!');
+ } else {
+ toastError(new Error(result.error || 'Failed to generate sample message'));
+ }
+ } catch (error) {
+ console.error('Error generating sample message:', error);
+ toastError(error);
+ }
+ };
+
+ const onDeleteMessage = () => {
+ const currentMessages = [...(body.grpc || [])];
+
+ currentMessages.splice(index, 1);
+
+ dispatch(
+ updateRequestBody({
+ content: currentMessages,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ })
+ );
+ };
+
+ const onPrettify = () => {
+ try {
+ const edits = format(content, undefined, { tabSize: 2, insertSpaces: true });
+ const prettyBodyJson = applyEdits(content, edits);
+
+ const currentMessages = [...(body.grpc || [])];
+ currentMessages[index] = {
+ name: name ? name : `message ${index + 1}`,
+ content: prettyBodyJson
+ };
+ dispatch(
+ updateRequestBody({
+ content: currentMessages,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ })
+ );
+ } catch (e) {
+ toastError(new Error('Unable to prettify. Invalid JSON format.'));
+ }
+ };
+
+ const getContainerHeight = (canClientSendMultipleMessages && body.grpc.length > 1) ? `${isCollapsed ? "" : "h-80"}` : "h-full"
+
+ return (
+
+
+
+ {isCollapsed ?
+ :
+
+ }
+ {`Message ${canClientStream ? index + 1 : ''}`}
+
+ e.stopPropagation()}>
+
+
+
+
+
+
+
+
+
+
+
+
+ {canClientStream && (
+
+
+
+
+
+ )}
+
+ {index > 0 && (
+
+
+
+
+
+ )}
+
+
+
+ {!isCollapsed && (
+
+
+
+ )}
+
+ )
+}
+
+const GrpcBody = ({ item, collection, handleRun }) => {
+ const preferences = useSelector((state) => state.app.preferences);
+ const isVerticalLayout = preferences?.layout?.responsePaneOrientation === 'vertical';
+ const dispatch = useDispatch();
+ const [collapsedMessages, setCollapsedMessages] = useState([]);
+ const messagesContainerRef = useRef(null);
+ const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body');
+
+ const methodType = item.draft ? get(item, 'draft.request.methodType') : get(item, 'request.methodType');
+ const canClientSendMultipleMessages = methodType === 'client-streaming' || methodType === 'bidi-streaming';
+
+ // Auto-scroll to the latest message when messages are added
+ useEffect(() => {
+ if (messagesContainerRef.current && body?.grpc?.length > 0) {
+ const container = messagesContainerRef.current;
+ container.scrollTop = container.scrollHeight;
+ }
+ }, [body?.grpc?.length]);
+
+ const toggleMessageCollapse = (index) => {
+ setCollapsedMessages(prev => {
+ if (prev.includes(index)) {
+ return prev.filter(i => i !== index);
+ } else {
+ return [...prev, index];
+ }
+ });
+ };
+
+ const addNewMessage = () => {
+ const currentMessages = Array.isArray(body.grpc)
+ ? [...body.grpc]
+ : [];
+
+ currentMessages.push({
+ name: `message ${currentMessages.length + 1}`,
+ content: '{}'
+ });
+
+ dispatch(
+ updateRequestBody({
+ content: currentMessages,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ })
+ );
+ };
+
+
+ if (!body?.grpc || !Array.isArray(body.grpc)) {
+ return (
+
+
+ No gRPC messages available
+
+
+
+ Add First Message
+
+
+
+
+ );
+ }
+
+ return (
+
+
+ {body.grpc
+ .filter((_, index) => canClientSendMultipleMessages || index === 0)
+ .map((message, index) => (
+ toggleMessageCollapse(index)}
+ handleRun={handleRun}
+ canClientSendMultipleMessages={canClientSendMultipleMessages}
+ />
+ ))}
+
+
+ {canClientSendMultipleMessages && (
+
+
+
+
+ Add Message
+
+
+
+ )}
+
+ );
+};
+
+export default GrpcBody;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcQueryUrl/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/GrpcQueryUrl/StyledWrapper.js
new file mode 100644
index 000000000..64c29be51
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcQueryUrl/StyledWrapper.js
@@ -0,0 +1,119 @@
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ height: 2.3rem;
+
+ .method-selector-container {
+ background-color: ${(props) => props.theme.requestTabPanel.url.bg};
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ }
+
+ .input-container {
+ background-color: ${(props) => props.theme.requestTabPanel.url.bg};
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+
+ input {
+ background-color: ${(props) => props.theme.requestTabPanel.url.bg};
+ outline: none;
+ box-shadow: none;
+
+ &:focus {
+ outline: none !important;
+ box-shadow: none !important;
+ }
+ }
+ }
+
+ .caret {
+ color: rgb(140, 140, 140);
+ fill: rgb(140 140 140);
+ position: relative;
+ top: 1px;
+ }
+
+ .infotip {
+ position: relative;
+ display: inline-block;
+ cursor: pointer;
+ }
+
+ .infotip:hover .infotip-text {
+ visibility: visible;
+ opacity: 1;
+ }
+
+ .infotip-text {
+ visibility: hidden;
+ width: auto;
+ background-color: ${(props) => props.theme.requestTabs.active.bg};
+ color: ${(props) => props.theme.text};
+ text-align: center;
+ border-radius: 4px;
+ padding: 4px 8px;
+ position: absolute;
+ z-index: 1;
+ bottom: 34px;
+ left: 50%;
+ transform: translateX(-50%);
+ opacity: 0;
+ transition: opacity 0.3s;
+ white-space: nowrap;
+ }
+
+ .infotip-text::after {
+ content: '';
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ margin-left: -4px;
+ border-width: 4px;
+ border-style: solid;
+ border-color: ${(props) => props.theme.requestTabs.active.bg} transparent transparent transparent;
+ }
+
+ .shortcut {
+ font-size: 0.625rem;
+ }
+
+ @keyframes pulse {
+ 0% {
+ opacity: 0.4;
+ }
+ 50% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0.4;
+ }
+ }
+
+ .connection-status-strip {
+ animation: pulse 1.5s ease-in-out infinite;
+ background-color: ${(props) => props.theme.colors.text.green};
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 2px;
+ }
+
+ /* Method dropdown styling */
+ .method-dropdown {
+ margin-right: 8px;
+ position: relative;
+ z-index: 10;
+ }
+
+ .dropdown-item {
+ padding: 8px 12px;
+ cursor: pointer;
+
+ &:hover {
+ background-color: ${(props) => props.theme.dropdown.hoverBg};
+ }
+ }
+`;
+
+export default Wrapper;
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcQueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/GrpcQueryUrl/index.js
new file mode 100644
index 000000000..150736ae3
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcQueryUrl/index.js
@@ -0,0 +1,1028 @@
+import React, { useState, useEffect, useRef, forwardRef, useCallback, useMemo } from 'react';
+import get from 'lodash/get';
+import { useDispatch, useSelector } from 'react-redux';
+import { requestUrlChanged, updateRequestMethod, updateRequestProtoPath } from 'providers/ReduxStore/slices/collections';
+import { saveRequest, browseFiles, loadGrpcMethodsFromReflection, openCollectionSettings, generateGrpcurlCommand } from 'providers/ReduxStore/slices/collections/actions';
+import { useTheme } from 'providers/Theme';
+import SingleLineEditor from 'components/SingleLineEditor/index';
+import { isMacOS } from 'utils/common/platform';
+import { getRelativePath, getBasename, getAbsoluteFilePath } from 'utils/common/path';
+import useLocalStorage from 'hooks/useLocalStorage/index';
+import StyledWrapper from './StyledWrapper';
+import ToggleSwitch from 'components/ToggleSwitch/index';
+import {
+ IconX,
+ IconCheck,
+ IconRefresh,
+ IconDeviceFloppy,
+ IconArrowRight,
+ IconCode,
+ IconFile,
+ IconChevronDown,
+ IconSettings,
+ IconAlertCircle,
+ IconCopy
+} from '@tabler/icons';
+import toast from 'react-hot-toast';
+import {
+ loadGrpcMethodsFromProtoFile,
+ cancelGrpcConnection,
+ endGrpcConnection
+} from 'utils/network/index';
+import Dropdown from 'components/Dropdown/index';
+import {
+ IconGrpcUnary,
+ IconGrpcClientStreaming,
+ IconGrpcServerStreaming,
+ IconGrpcBidiStreaming
+} from 'components/Icons/Grpc';
+import Modal from 'components/Modal/index';
+import CodeEditor from 'components/CodeEditor';
+import { debounce } from 'lodash';
+import { getPropertyFromDraftOrRequest } from 'utils/collections';
+import { existsSync } from 'utils/filesystem';
+
+// Constants for gRPC method types
+const STREAMING_METHOD_TYPES = ['client-streaming', 'server-streaming', 'bidi-streaming'];
+const CLIENT_STREAMING_METHOD_TYPES = ['client-streaming', 'bidi-streaming'];
+
+const GrpcurlModal = ({ isOpen, onClose, command }) => {
+ const { displayedTheme } = useTheme();
+ const [copied, setCopied] = useState(false);
+ const preferences = useSelector((state) => state.app.preferences);
+
+ const handleCopy = async () => {
+ try {
+ await navigator.clipboard.writeText(command);
+ setCopied(true);
+ toast.success('Command copied to clipboard');
+ setTimeout(() => setCopied(false), 2000);
+ } catch (error) {
+ toast.error('Failed to copy command');
+ }
+ };
+
+ return (
+
+ Generate gRPCurl Command
+ BETA
+
+ }
+ size="lg"
+ hideFooter={true}
+ >
+
+
+
+
+
+ {copied ? : }
+
+
+
+
+
+
+
+ );
+};
+
+const GrpcQueryUrl = ({ item, collection, handleRun }) => {
+ const { theme, storedTheme } = useTheme();
+ const dispatch = useDispatch();
+ const method = getPropertyFromDraftOrRequest(item, 'request.method');
+ const type = getPropertyFromDraftOrRequest(item, 'request.type');
+ const url = getPropertyFromDraftOrRequest(item, 'request.url', '');
+ const protoPath = getPropertyFromDraftOrRequest(item, 'request.protoPath');
+ const isMac = isMacOS();
+ const saveShortcut = isMac ? 'Cmd + S' : 'Ctrl + S';
+ const editorRef = useRef(null);
+ const isConnectionActive = useSelector((state) => state.collections.activeConnections.includes(item.uid));
+ const [protoFilePath, setProtoFilePath] = useState(protoPath);
+ const [grpcMethods, setGrpcMethods] = useState([]);
+ const [isLoadingMethods, setIsLoadingMethods] = useState(false);
+ const [selectedGrpcMethod, setSelectedGrpcMethod] = useState({
+ path: method,
+ type: type
+ });
+ const methodDropdownRef = useRef();
+ const protoDropdownRef = useRef();
+ const haveFetchedMethodsRef = useRef(false);
+ const [showGrpcurlModal, setShowGrpcurlModal] = useState(false);
+ const [grpcurlCommand, setGrpcurlCommand] = useState('');
+ const [isReflectionMode, setIsReflectionMode] = useState(false);
+ const collectionProtoFiles = get(collection, 'brunoConfig.grpc.protoFiles', []);
+ const [reflectionCache, setReflectionCache] = useLocalStorage('bruno.grpc.reflectionCache', {});
+ const [protofileCache, setProtofileCache] = useLocalStorage('bruno.grpc.protofileCache', {});
+ const fileExistsCache = useRef(new Map());
+ const [showProtoDropdown, setShowProtoDropdown] = useState(false);
+
+ const fileExists = useCallback(async (filePath) => {
+ if (!filePath) return false;
+
+ if (fileExistsCache.current.has(filePath)) {
+ return fileExistsCache.current.get(filePath);
+ }
+
+ try {
+ const absolutePath = getAbsoluteFilePath(filePath, collection.pathname);
+ const exists = await existsSync(absolutePath);
+ fileExistsCache.current.set(filePath, exists);
+ return exists;
+ } catch (error) {
+ console.error('Error checking if file exists:', error);
+ return false;
+ }
+ }, [collection.pathname]);
+
+ const [collectionProtoFilesExistence, setCollectionProtoFilesExistence] = useState([]);
+
+ useEffect(() => {
+ const fetchCollectionProtoFilesExistence = async () => {
+ if (!collectionProtoFiles) return;
+ const existence = await Promise.all(collectionProtoFiles.map(async (protoFile) => {
+ const absolutePath = getAbsoluteFilePath(protoFile.path, collection.pathname);
+ const exists = await fileExists(absolutePath)
+ return {
+ path: protoFile.path,
+ absolutePath,
+ exists
+ }
+ }));
+ setCollectionProtoFilesExistence(existence);
+ };
+ fetchCollectionProtoFilesExistence();
+ }, [fileExists]);
+
+ const invalidProtoFiles = useMemo(() => {
+ return collectionProtoFilesExistence.filter(file => !file.exists);
+ }, [collectionProtoFilesExistence]);
+
+ const currentProtoFileExists = useMemo(() => {
+ return fileExists(protoFilePath);
+ }, [protoFilePath, fileExists]);
+
+ const onMethodDropdownCreate = (ref) => (methodDropdownRef.current = ref);
+ const onProtoDropdownCreate = (ref) => (protoDropdownRef.current = ref);
+
+
+ const isStreamingMethod = selectedGrpcMethod && selectedGrpcMethod.type && STREAMING_METHOD_TYPES.includes(selectedGrpcMethod.type);
+ const isClientStreamingMethod = selectedGrpcMethod && selectedGrpcMethod.type && CLIENT_STREAMING_METHOD_TYPES.includes(selectedGrpcMethod.type);
+
+ const onSave = (finalValue) => {
+ dispatch(saveRequest(item.uid, collection.uid));
+ };
+
+ const onUrlChange = (value) => {
+ if (!editorRef.current?.editor) return;
+ const editor = editorRef.current.editor;
+ const cursor = editor.getCursor();
+
+ const finalUrl = value?.trim() || value;
+
+ dispatch(
+ requestUrlChanged({
+ itemUid: item.uid,
+ collectionUid: collection.uid,
+ url: finalUrl
+ })
+ );
+
+ // Restore cursor position only if URL was trimmed
+ if (finalUrl !== value) {
+ setTimeout(() => {
+ if (editor) {
+ editor.setCursor(cursor);
+ }
+ }, 0);
+ }
+
+ if(!protoFilePath && value) {
+ setIsReflectionMode(true);
+ handleReflection(finalUrl);
+ }
+ };
+
+ const onMethodSelect = ({ path, type }) => {
+ if (isConnectionActive) {
+ cancelGrpcConnection(item.uid)
+ .then(() => {
+ toast.success('gRPC connection cancelled');
+ })
+ .catch((err) => {
+ console.error('Failed to cancel gRPC connection:', err);
+ });
+ }
+
+ dispatch(
+ updateRequestMethod({
+ method: path,
+ methodType: type,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ })
+ );
+ };
+
+ const handleReflection = async (url, isManualRefresh = false) => {
+ if (!url) return;
+
+ const cachedMethods = reflectionCache[url];
+ if (!isManualRefresh && cachedMethods && !isLoadingMethods) {
+ setGrpcMethods(cachedMethods);
+ setProtoFilePath('');
+ setIsReflectionMode(true);
+ const isDuplicateSave = !item.request.protoPath;
+ if (!isDuplicateSave) {
+ dispatch(updateRequestProtoPath({
+ protoPath: '',
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ }));
+ }
+
+ if (cachedMethods && cachedMethods.length > 0) {
+ const haveSelectedMethod =
+ selectedGrpcMethod && cachedMethods.some((method) => method.path === selectedGrpcMethod.path);
+ if (!haveSelectedMethod) {
+ setSelectedGrpcMethod(null);
+ onMethodSelect({ path: '', type: '' });
+ } else if (selectedGrpcMethod) {
+ // Update the method type for the currently selected method to ensure it matches
+ const currentMethod = cachedMethods.find((method) => method.path === selectedGrpcMethod.path);
+ if (currentMethod) {
+ const methodType = currentMethod.type;
+ setSelectedGrpcMethod({
+ path: selectedGrpcMethod.path,
+ type: methodType
+ });
+ }
+ }
+ return;
+ }
+ }
+
+ setIsLoadingMethods(true);
+ try {
+ const { methods, error } = await dispatch(loadGrpcMethodsFromReflection(item, collection.uid, url));
+
+ if (error) {
+ console.error('Error loading gRPC methods:', error);
+ toast.error(`Failed to load gRPC methods: ${error.message || 'Unknown error'}`);
+ return;
+ }
+
+ // Cache the methods for this URL
+ setReflectionCache(prevCache => ({
+ ...prevCache,
+ [url]: methods
+ }));
+
+ setGrpcMethods(methods);
+ setProtoFilePath('');
+ setIsReflectionMode(true);
+ const isDuplicateSave = !item.request.protoPath;
+ if (!isDuplicateSave) {
+ dispatch(updateRequestProtoPath({
+ protoPath: '',
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ }));
+ }
+
+ if (methods && methods.length > 0) {
+ const haveSelectedMethod =
+ selectedGrpcMethod && methods.some((method) => method.path === selectedGrpcMethod.path);
+ if (!haveSelectedMethod) {
+ setSelectedGrpcMethod(null);
+ onMethodSelect({ path: '', type: '' });
+ } else if (selectedGrpcMethod) {
+ // Update the method type for the currently selected method to ensure it matches
+ const currentMethod = methods.find((method) => method.path === selectedGrpcMethod.path);
+ if (currentMethod) {
+ const methodType = currentMethod.type;
+ setSelectedGrpcMethod({
+ path: selectedGrpcMethod.path,
+ type: methodType
+ });
+ }
+ }
+ toast.success(`Loaded ${methods.length} gRPC methods from reflection`);
+ }
+ } catch (error) {
+ console.error('Error loading gRPC methods:', error);
+ toast.error('Failed to load gRPC methods from reflection');
+ } finally {
+ setIsLoadingMethods(false);
+ }
+ };
+
+ const handleGrpcurl = async (url) => {
+ if (!url) {
+ toast.error('Please enter a valid gRPC server URL');
+ return;
+ }
+
+ if (!selectedGrpcMethod?.path) {
+ toast.error('Please select a gRPC method');
+ return;
+ }
+
+ try {
+ const result = await dispatch(generateGrpcurlCommand(item, collection.uid));
+
+ if (result.success) {
+ setGrpcurlCommand(result.command);
+ setShowGrpcurlModal(true);
+ } else {
+ toast.error(result.error || 'Failed to generate grpcurl command');
+ }
+ } catch (error) {
+ console.error('Error generating grpcurl command:', error);
+ toast.error('Failed to generate grpcurl command');
+ }
+ };
+
+ // Add a new function to group methods by service
+ const groupMethodsByService = (methods) => {
+ if (!methods || !methods.length) return {};
+
+ const groupedMethods = {};
+
+ methods.forEach(method => {
+ // The format is "/service.ServiceName/MethodName"
+ const pathWithoutLeadingSlash = method.path.startsWith('/') ? method.path.slice(1) : method.path;
+ const parts = pathWithoutLeadingSlash.split('/');
+
+ // The service is the part before the last slash
+ const serviceName = parts[0] || 'Default';
+ // The method name is the part after the last slash
+ const methodName = parts[1] || method.path;
+
+ // Store the extracted method name for easier display
+ const enhancedMethod = {
+ ...method,
+ serviceName,
+ methodName
+ };
+
+ if (!groupedMethods[serviceName]) {
+ groupedMethods[serviceName] = [];
+ }
+
+ groupedMethods[serviceName].push(enhancedMethod);
+ });
+
+ return groupedMethods;
+ };
+
+ const MethodsDropdownIcon = forwardRef((props, ref) => {
+ return (
+
+ {selectedGrpcMethod && {getIconForMethodType(selectedGrpcMethod.type)} }
+
+ {selectedGrpcMethod ? (
+
+ {selectedGrpcMethod.path.split('.').at(-1) || selectedGrpcMethod.path}
+
+ ) : (
+ Select Method
+ )}
+
+
+
+ );
+ });
+
+ const ProtoFileDropdownIcon = forwardRef((props, ref) => {
+ return (
+ setShowProtoDropdown(prev => !prev)}>
+ {isReflectionMode ? (<>>
+ ) : (
+
+ )}
+
+ {isReflectionMode ? 'Using Reflection' : (protoFilePath ? getBasename(protoFilePath) : 'Select Proto File')}
+
+
+
+ );
+ });
+
+ const handleGrpcMethodSelect = (method) => {
+ const methodType = method.type
+ setSelectedGrpcMethod({
+ path: method.path,
+ type: methodType
+ });
+ onMethodSelect({ path: method.path, type: methodType });
+ };
+
+ const getIconForMethodType = (type) => {
+ switch (type) {
+ case 'unary':
+ return ;
+ case 'client-streaming':
+ return ;
+ case 'server-streaming':
+ return ;
+ case 'bidi-streaming':
+ return ;
+ default:
+ return ;
+ }
+ };
+
+ const handleCancelConnection = (e) => {
+ e.stopPropagation();
+
+ cancelGrpcConnection(item.uid)
+ .then(() => {
+ toast.success('gRPC connection cancelled');
+ })
+ .catch((err) => {
+ console.error('Failed to cancel gRPC connection:', err);
+ toast.error('Failed to cancel gRPC connection');
+ });
+ };
+
+ const handleEndConnection = (e) => {
+ e.stopPropagation();
+
+ endGrpcConnection(item.uid)
+ .then(() => {
+ toast.success('gRPC stream ended');
+ })
+ .catch((err) => {
+ console.error('Failed to end gRPC stream:', err);
+ toast.error('Failed to end gRPC stream');
+ });
+ };
+
+ const handleSelectCollectionProtoFile = (protoFile) => {
+ try {
+ if (!protoFile) {
+ toast.error('No proto file selected');
+ return;
+ }
+
+ // Get the absolute path from the relative path
+ const absolutePath = protoFile.absolutePath;
+
+ if (!protoFile.exists) {
+ toast.error(`Proto file not found: ${protoFile.path}`);
+ return;
+ }
+
+ setProtoFilePath(protoFile.path);
+ setIsReflectionMode(false);
+
+ dispatch(updateRequestProtoPath({
+ protoPath: protoFile.path,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ }));
+
+ loadMethodsFromProtoFile(absolutePath);
+ } catch (error) {
+ console.error('Error selecting collection proto file:', error);
+ toast.error('Failed to select collection proto file');
+ }
+ };
+
+ const handleResetProtoFile = () => {
+ setProtoFilePath('');
+ setIsReflectionMode(true);
+ const isDuplicateSave = !item.request.protoPath;
+ if (!isDuplicateSave) {
+ dispatch(updateRequestProtoPath({
+ protoPath: '',
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ }));
+ }
+ setGrpcMethods([]);
+ setSelectedGrpcMethod(null);
+ onMethodSelect({ path: '', type: '' });
+ toast.success('Proto file reset');
+ };
+
+ const loadMethodsFromProtoFile = async (filePath, isManualRefresh = false) => {
+ if (!filePath) {
+ toast.error('No proto file selected');
+ return;
+ };
+ const absolutePath = getAbsoluteFilePath(filePath, collection.pathname);
+
+ // Check if we have cached methods for this proto file
+ const cachedMethods = protofileCache[absolutePath];
+ if (cachedMethods && !isLoadingMethods && !isManualRefresh) {
+ setGrpcMethods(cachedMethods);
+
+ if (cachedMethods && cachedMethods.length > 0) {
+ // Check if currently selected method is still valid
+ const haveSelectedMethod =
+ selectedGrpcMethod && cachedMethods.some((method) => method.path === selectedGrpcMethod.path);
+ if (!haveSelectedMethod) {
+ setSelectedGrpcMethod(null);
+ onMethodSelect({ path: '', type: '' });
+ } else {
+ // Update the method type for the currently selected method to ensure it matches
+ const currentMethod = cachedMethods.find((method) => method.path === selectedGrpcMethod.path);
+ if (currentMethod) {
+ const methodType = currentMethod.type;
+ setSelectedGrpcMethod({
+ path: selectedGrpcMethod.path,
+ type: methodType
+ });
+ }
+ }
+ }
+ return;
+ }
+
+ setIsLoadingMethods(true);
+ try {
+ const { methods, error } = await loadGrpcMethodsFromProtoFile(absolutePath);
+
+ if (error) {
+ console.error('Error loading gRPC methods:', error);
+ toast.error(`Failed to load gRPC methods: ${error.message || 'Unknown error'}`);
+ return;
+ }
+
+ // Cache the methods for this proto file
+ setProtofileCache(prevCache => ({
+ ...prevCache,
+ [absolutePath]: methods
+ }));
+
+ setGrpcMethods(methods);
+
+ if (methods && methods.length > 0) {
+ toast.success(`Loaded ${methods.length} gRPC methods from proto file`);
+
+ // Check if currently selected method is still valid
+ const haveSelectedMethod =
+ selectedGrpcMethod && methods.some((method) => method.path === selectedGrpcMethod.path);
+ if (!haveSelectedMethod) {
+ setSelectedGrpcMethod(null);
+ onMethodSelect({ path: '', type: '' });
+ } else {
+ // Update the method type for the currently selected method to ensure it matches
+ const currentMethod = methods.find((method) => method.path === selectedGrpcMethod.path);
+ if (currentMethod) {
+ const methodType = currentMethod.type;
+ setSelectedGrpcMethod({
+ path: selectedGrpcMethod.path,
+ type: methodType
+ });
+ }
+ }
+ } else {
+ toast.warning('No gRPC methods found in proto file');
+ }
+ } catch (err) {
+ console.error('Error loading gRPC methods:', err);
+ toast.error('Failed to load gRPC methods from proto file');
+ } finally {
+ setIsLoadingMethods(false);
+ }
+ };
+
+ const handleSelectProtoFile = (e) => {
+ e.stopPropagation();
+ const filters = [{ name: 'Proto Files', extensions: ['proto'] }];
+
+ dispatch(browseFiles(filters, ['']))
+ .then((filePaths) => {
+ if (filePaths && filePaths.length > 0) {
+ const filePath = filePaths[0];
+ const relativePath = getRelativePath(filePath, collection.pathname);
+ setProtoFilePath(relativePath);
+ setIsReflectionMode(false);
+
+ dispatch(updateRequestProtoPath({
+ protoPath: relativePath,
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ }));
+
+ // Load methods from the newly selected proto file
+ const absolutePath = getAbsoluteFilePath(relativePath, collection.pathname);
+ loadMethodsFromProtoFile(absolutePath);
+ }
+ })
+ .catch((err) => {
+ console.error('Error selecting proto file:', err);
+ toast.error('Failed to select proto file');
+ });
+ };
+
+ const handleOpenCollectionGrpc = () => {
+ dispatch(openCollectionSettings(collection.uid, 'grpc'));
+ };
+
+ const debouncedOnUrlChange = debounce(onUrlChange, 1000);
+
+ useEffect(() => {
+ fileExistsCache.current.clear();
+ }, [collection.pathname]);
+
+ useEffect(() => {
+ if(haveFetchedMethodsRef.current) {
+ return;
+ }
+ haveFetchedMethodsRef.current = true;
+
+ if(protoFilePath) {
+ setIsReflectionMode(false);
+ loadMethodsFromProtoFile(protoFilePath);
+ return;
+ }
+ if (!url) return;
+ setIsReflectionMode(true);
+ handleReflection(url);
+
+ }, []);
+
+ return (
+
+
+
+ onSave(finalValue)}
+ theme={storedTheme}
+ onChange={(newValue) => debouncedOnUrlChange(newValue)}
+ onRun={handleRun}
+ collection={collection}
+ highlightPathParams={true}
+ item={item}
+ />
+
+ {grpcMethods && grpcMethods.length > 0 && (
+
+ } placement="bottom-end" style={{ maxWidth: "unset" }}>
+
+ {Object.entries(groupMethodsByService(grpcMethods)).map(([serviceName, methods], serviceIndex) => (
+
+
+ {serviceName || 'Default Service'}
+
+
+ {methods.map((method, methodIndex) => (
+ handleGrpcMethodSelect(method)}
+ >
+
+ {getIconForMethodType(method.type)}
+
+ {method.methodName}
+ {method.type}
+
+
+
+ ))}
+
+
+ ))}
+
+
+
+ )}
+
+
+ }
+ placement="bottom-end"
+ visible={showProtoDropdown}
+ onClickOutside={() => setShowProtoDropdown(false)}
+ >
+
+
+ {isReflectionMode ? "Using Reflection" : "Select Proto File"}
+
+
+ {/* Mode Toggle */}
+
+
+ Mode
+
+
+ Proto File
+
+ {
+ e.stopPropagation();
+ e.preventDefault();
+ setIsReflectionMode(!isReflectionMode);
+ if (!isReflectionMode) {
+ // Switching to reflection mode
+ setProtoFilePath('');
+ dispatch(updateRequestProtoPath({
+ protoPath: '',
+ itemUid: item.uid,
+ collectionUid: collection.uid
+ }));
+ if (url) {
+ handleReflection(url);
+ }
+ } else {
+ // Switching to proto file mode
+ setGrpcMethods([]);
+ setSelectedGrpcMethod(null);
+ onMethodSelect({ path: '', type: '' });
+ }
+ }}
+ size="2xs"
+ />
+
+ Reflection
+
+
+
+
+
+ {!isReflectionMode && (
+ <>
+ {collectionProtoFiles && collectionProtoFiles.length > 0 && (
+
+
+ From Collection Settings
+ {
+ e.stopPropagation();
+ handleOpenCollectionGrpc();
+ }}
+ className="text-neutral-500 hover:text-neutral-700 dark:hover:text-neutral-300"
+ >
+
+
+
+
+ {invalidProtoFiles.length > 0 && (
+
+
+
+ Some proto files could not be found. {
+ e.stopPropagation();
+ handleOpenCollectionGrpc();
+ }}
+ className="text-red-600 dark:text-red-400 underline hover:text-red-700 dark:hover:text-red-300 ml-1"
+ >
+ Manage proto files
+
+
+
+ )}
+
+
+ {collectionProtoFilesExistence.map((protoFile, index) => {
+ const isSelected = protoFilePath === protoFile.absolutePath;
+ const isInvalid = !protoFile.exists;
+
+ return (
+ {
+ if (!isInvalid) {
+ setShowProtoDropdown(false);
+ handleSelectCollectionProtoFile(protoFile);
+ }
+ }}
+ >
+
+
+
+
+
+ {getBasename(protoFile.absolutePath)}
+ {isInvalid && (
+
+
+
+ )}
+
+ {protoFile.path}
+
+
+
+
+ );
+ })}
+
+
+ )}
+
+ {collectionProtoFiles && collectionProtoFiles.length > 0 && (
+
+ )}
+
+ {protoFilePath && !collectionProtoFilesExistence.some(pf =>
+ pf.absolutePath === protoFilePath
+ ) && (
+
+ Current Proto File
+ {!currentProtoFileExists && (
+
+
+
+ Selected proto file not found. Please select a valid proto file from collection settings or browse for a new one.
+
+
+ )}
+
+
+
+
+
+
+ {getBasename(protoFilePath)}
+ {!currentProtoFileExists && (
+
+
+
+ )}
+
+ {protoFilePath}
+
+
+
+ {
+ e.stopPropagation();
+ handleResetProtoFile();
+ }}
+ >
+
+
+
+
+
+
+
+ )}
+
+
+ {
+ handleSelectProtoFile(e);
+ }}
+ >
+
+ Browse for Proto File
+
+
+ >
+ )}
+
+ {isReflectionMode && (
+
+
+ Using server reflection to discover gRPC methods.
+
+
+ )}
+
+
+
+
+ {
+ e.stopPropagation();
+ if (isReflectionMode) {
+ handleReflection(url, true);
+ } else if (protoFilePath) {
+ loadMethodsFromProtoFile(protoFilePath, true);
+ } else {
+ toast.error('No proto file selected');
+ }
+ }}
+ >
+
+
+ {isReflectionMode ? 'Refresh server reflection' : 'Refresh proto file methods'}
+
+
+
+ {
+ e.stopPropagation();
+ handleGrpcurl(url);
+ }}
+ >
+
+ Generate grpcurl command
+
+
+ {
+ e.stopPropagation();
+ if (!item.draft) return;
+ onSave();
+ }}
+ >
+
+
+ Save ({saveShortcut})
+
+
+
+ {isConnectionActive && isStreamingMethod && (
+
+
+
+ Cancel
+
+
+ {isClientStreamingMethod &&
+
+ }
+
+ )}
+
+ {(!isConnectionActive || !isStreamingMethod) && (
+ {
+ e.stopPropagation();
+ handleRun(e);
+ }}
+ >
+
+
+ )}
+
+
+ {isConnectionActive && isStreamingMethod && (
+
+ )}
+
+ {showGrpcurlModal && (
+ setShowGrpcurlModal(false)}
+ command={grpcurlCommand}
+ />
+ )}
+
+ );
+};
+
+export default GrpcQueryUrl;
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/GrpcAuthMode/index.js b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/GrpcAuthMode/index.js
new file mode 100644
index 000000000..3b95b708f
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/GrpcAuthMode/index.js
@@ -0,0 +1,85 @@
+import React, { useRef, forwardRef } from 'react';
+import get from 'lodash/get';
+import { IconCaretDown } from '@tabler/icons';
+import Dropdown from 'components/Dropdown';
+import { useDispatch } from 'react-redux';
+import { updateRequestAuthMode } from 'providers/ReduxStore/slices/collections';
+import { humanizeRequestAuthMode } from 'utils/collections';
+import StyledWrapper from '../../../Auth/AuthMode/StyledWrapper';
+
+const GrpcAuthMode = ({ item, collection }) => {
+ const dispatch = useDispatch();
+ const dropdownTippyRef = useRef();
+ const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
+ const authMode = item.draft ? get(item, 'draft.request.auth.mode') : get(item, 'request.auth.mode');
+
+ const authModes = [
+ {
+ name: 'Basic Auth',
+ mode: 'basic'
+ },
+ {
+ name: 'Bearer Token',
+ mode: 'bearer'
+ },
+ {
+ name: 'API Key',
+ mode: 'apikey'
+ },
+ {
+ name: 'OAuth2',
+ mode: 'oauth2'
+ },
+ {
+ name: 'Inherit',
+ mode: 'inherit'
+ },
+ {
+ name: 'No Auth',
+ mode: 'none'
+ }
+ ];
+
+ const Icon = forwardRef((props, ref) => {
+ return (
+
+ {humanizeRequestAuthMode(authMode)}
+
+ );
+ });
+
+ const onModeChange = (value) => {
+ dispatch(
+ updateRequestAuthMode({
+ itemUid: item.uid,
+ collectionUid: collection.uid,
+ mode: value
+ })
+ );
+ };
+
+ const onClickHandler = (mode) => {
+ dropdownTippyRef?.current?.hide();
+ onModeChange(mode);
+ };
+
+ return (
+
+
+ } placement="bottom-end">
+ {authModes.map((authMode) => (
+ onClickHandler(authMode.mode)}
+ >
+ {authMode.name}
+
+ ))}
+
+
+
+ );
+};
+
+export default GrpcAuthMode;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/StyledWrapper.js
new file mode 100644
index 000000000..f76b0d9a4
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/StyledWrapper.js
@@ -0,0 +1,9 @@
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ .inherit-mode-text {
+ color: ${(props) => props.theme.colors.text.yellow};
+ }
+`;
+
+export default Wrapper;
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/index.js b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/index.js
new file mode 100644
index 000000000..b30be89e5
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/GrpcAuth/index.js
@@ -0,0 +1,125 @@
+import React, { useEffect } from 'react';
+import get from 'lodash/get';
+import { useDispatch } from 'react-redux';
+import GrpcAuthMode from './GrpcAuthMode';
+import BearerAuth from '../../Auth/BearerAuth';
+import BasicAuth from '../../Auth/BasicAuth';
+import ApiKeyAuth from '../../Auth/ApiKeyAuth';
+import OAuth2 from '../../Auth/OAuth2/index';
+import StyledWrapper from './StyledWrapper';
+import { humanizeRequestAuthMode } from 'utils/collections';
+import { getTreePathFromCollectionToItem } from 'utils/collections/index';
+import { updateRequestAuthMode, updateAuth } from 'providers/ReduxStore/slices/collections';
+import { saveRequest } from 'providers/ReduxStore/slices/collections/actions';
+
+// List of auth modes supported by gRPC
+const supportedGrpcAuthModes = ['basic', 'bearer', 'apikey', 'oauth2', 'none', 'inherit'];
+
+const GrpcAuth = ({ item, collection }) => {
+ const dispatch = useDispatch();
+ const authMode = item.draft ? get(item, 'draft.request.auth.mode') : get(item, 'request.auth.mode');
+ const requestTreePath = getTreePathFromCollectionToItem(collection, item);
+
+ const request = item.draft
+ ? get(item, 'draft.request', {})
+ : get(item, 'request', {});
+
+ const save = () => {
+ return saveRequest(item.uid, collection.uid);
+ };
+
+ // Reset to 'none' if current auth mode is not supported by gRPC
+ useEffect(() => {
+ if (authMode && !supportedGrpcAuthModes.includes(authMode)) {
+ dispatch(
+ updateRequestAuthMode({
+ itemUid: item.uid,
+ collectionUid: collection.uid,
+ mode: 'none'
+ })
+ );
+ }
+ }, [authMode, collection.uid, dispatch, item.uid]);
+
+ const getEffectiveAuthSource = () => {
+ if (authMode !== 'inherit') return null;
+
+ const collectionAuth = get(collection, 'root.request.auth');
+ let effectiveSource = {
+ type: 'collection',
+ name: 'Collection',
+ auth: collectionAuth
+ };
+
+ // Check folders in reverse to find the closest auth configuration
+ for (let i of [...requestTreePath].reverse()) {
+ if (i.type === 'folder') {
+ const folderAuth = get(i, 'root.request.auth');
+ if (folderAuth && folderAuth.mode && folderAuth.mode !== 'none' && folderAuth.mode !== 'inherit') {
+ effectiveSource = {
+ type: 'folder',
+ name: i.name,
+ auth: folderAuth
+ };
+ break;
+ }
+ }
+ }
+
+ return effectiveSource;
+ };
+
+ const getAuthView = () => {
+ switch (authMode) {
+ case 'basic': {
+ return ;
+ }
+ case 'bearer': {
+ return ;
+ }
+ case 'apikey': {
+ return ;
+ }
+ case 'oauth2': {
+ return ;
+ }
+ case 'inherit': {
+ const source = getEffectiveAuthSource();
+
+ // Only show inherited auth if it's one of the supported types
+ if (source && supportedGrpcAuthModes.includes(source.auth?.mode)) {
+ return (
+ <>
+
+ Auth inherited from {source.name}:
+ {humanizeRequestAuthMode(source.auth?.mode)}
+
+ >
+ );
+ } else {
+ return (
+ <>
+
+ Inherited auth not supported by gRPC. Using no auth instead.
+
+ >
+ );
+ }
+ }
+ default: {
+ return null;
+ }
+ }
+ };
+
+ return (
+
+
+
+
+ {getAuthView()}
+
+ );
+};
+
+export default GrpcAuth;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/StyledWrapper.js
new file mode 100644
index 000000000..e6a766672
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/StyledWrapper.js
@@ -0,0 +1,34 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ div.tabs {
+ div.tab {
+ padding: 6px 0px;
+ border: none;
+ border-bottom: solid 2px transparent;
+ margin-right: 1.25rem;
+ color: var(--color-tab-inactive);
+ cursor: pointer;
+
+ &:focus,
+ &:active,
+ &:focus-within,
+ &:focus-visible,
+ &:target {
+ outline: none !important;
+ box-shadow: none !important;
+ }
+
+ &.active {
+ color: ${(props) => props.theme.tabs.active.color} !important;
+ border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
+ }
+
+ .content-indicator {
+ color: ${(props) => props.theme.text}
+ }
+ }
+ }
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.js b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.js
new file mode 100644
index 000000000..ef961b79d
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GrpcRequestPane/index.js
@@ -0,0 +1,124 @@
+import React from 'react';
+import classnames from 'classnames';
+import { useSelector, useDispatch } from 'react-redux';
+import { updateRequestPaneTab } from 'providers/ReduxStore/slices/tabs';
+import RequestHeaders from 'components/RequestPane/RequestHeaders';
+import GrpcBody from 'components/RequestPane/GrpcBody';
+import GrpcAuth from './GrpcAuth/index';
+import StatusDot from 'components/StatusDot/index';
+import HeightBoundContainer from 'ui/HeightBoundContainer';
+import StyledWrapper from './StyledWrapper';
+import { find, get } from 'lodash';
+import Documentation from 'components/Documentation/index';
+import { useEffect } from 'react';
+import { getPropertyFromDraftOrRequest } from 'utils/collections/index';
+
+const GrpcRequestPane = ({ item, collection, handleRun }) => {
+ const dispatch = useDispatch();
+ const tabs = useSelector((state) => state.tabs.tabs);
+ const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
+
+ const selectTab = (tab) => {
+ dispatch(
+ updateRequestPaneTab({
+ uid: item.uid,
+ requestPaneTab: tab
+ })
+ );
+ };
+
+ const getTabPanel = (tab) => {
+ switch (tab) {
+ case 'body': {
+ return ;
+ }
+ case 'headers': {
+ return ;
+ }
+ case 'auth': {
+ return ;
+ }
+ case 'docs': {
+ return ;
+ }
+ default: {
+ return 404 | Not found ;
+ }
+ }
+ };
+
+ if (!activeTabUid) {
+ return Something went wrong ;
+ }
+
+ const focusedTab = find(tabs, (t) => t.uid === activeTabUid);
+ if (!focusedTab || !focusedTab.uid || !focusedTab.requestPaneTab) {
+ return An error occurred! ;
+ }
+
+ const getTabClassname = (tabName) => {
+ return classnames(`tab select-none ${tabName}`, {
+ active: tabName === focusedTab.requestPaneTab
+ });
+ };
+
+ const isMultipleContentTab = ['script', 'vars', 'auth', 'docs'].includes(focusedTab.requestPaneTab);
+ const body = getPropertyFromDraftOrRequest(item, 'request.body');
+ const headers = getPropertyFromDraftOrRequest(item, 'request.headers');
+ const docs = getPropertyFromDraftOrRequest(item, 'request.docs');
+ const auth = getPropertyFromDraftOrRequest(item, 'request.auth');
+
+ const activeHeadersLength = headers.filter((header) => header.enabled).length;
+ const grpcMessagesCount = body?.grpc?.length || 0;
+
+ // Determine if this is a client streaming request
+ const request = item.draft ? item.draft.request : item.request;
+ const isClientStreaming = request.methodType === 'client-streaming' || request.methodType === 'bidi-streaming';
+
+ useEffect(() => {
+ // Only set the tab to 'body' if no tab is currently set
+ if (!focusedTab?.requestPaneTab) {
+ selectTab('body');
+ }
+ }, []);
+
+ return (
+
+
+ selectTab('body')}>
+ Message
+ {grpcMessagesCount > 0 && (
+ isClientStreaming ? (
+ {grpcMessagesCount}
+ ) : (
+
+ )
+ )}
+
+ selectTab('headers')}>
+ Metadata
+ {activeHeadersLength > 0 && {activeHeadersLength}}
+
+ selectTab('auth')}>
+ Auth
+ {auth.mode !== 'none' && }
+
+ selectTab('docs')}>
+ Docs
+ {docs && docs.length > 0 && }
+
+
+
+
+ {getTabPanel(focusedTab.requestPaneTab)}
+
+
+
+ );
+};
+
+export default GrpcRequestPane;
diff --git a/packages/bruno-app/src/components/RequestPane/QueryParams/index.js b/packages/bruno-app/src/components/RequestPane/QueryParams/index.js
index 0b1b9df9c..b5c2c69a7 100644
--- a/packages/bruno-app/src/components/RequestPane/QueryParams/index.js
+++ b/packages/bruno-app/src/components/RequestPane/QueryParams/index.js
@@ -147,7 +147,7 @@ const QueryParams = ({ item, collection }) => {
diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js
index 2035ba00c..3fe47b041 100644
--- a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js
+++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js
@@ -20,6 +20,7 @@ const QueryUrl = ({ item, collection, handleRun }) => {
const isMac = isMacOS();
const saveShortcut = isMac ? 'Cmd + S' : 'Ctrl + S';
const editorRef = useRef(null);
+ const isGrpc = item.type === 'grpc-request';
const [methodSelectorWidth, setMethodSelectorWidth] = useState(90);
const [generateCodeItemModalOpen, setGenerateCodeItemModalOpen] = useState(false);
@@ -80,7 +81,14 @@ const QueryUrl = ({ item, collection, handleRun }) => {
return (
-
+ {isGrpc ? (
+
+ gRPC
+
+
+ ) : (
+
+ )}
{
} placement="bottom-end">
- Form
- {
- dropdownTippyRef.current.hide();
- onModeChange('multipartForm');
- }}
- >
- Multipart Form
-
- {
- dropdownTippyRef.current.hide();
- onModeChange('formUrlEncoded');
- }}
- >
- Form URL Encoded
-
- Raw
- {
- dropdownTippyRef.current.hide();
- onModeChange('json');
- }}
- >
- JSON
-
- {
- dropdownTippyRef.current.hide();
- onModeChange('xml');
- }}
- >
- XML
-
- {
- dropdownTippyRef.current.hide();
- onModeChange('text');
- }}
- >
- TEXT
-
- {
- dropdownTippyRef.current.hide();
- onModeChange('sparql');
- }}
- >
- SPARQL
-
- Other
- {
- dropdownTippyRef.current.hide();
- onModeChange('file');
- }}
- >
- File / Binary
-
- {
- dropdownTippyRef.current.hide();
- onModeChange('none');
- }}
- >
- No Body
-
+ Form
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('multipartForm');
+ }}
+ >
+ Multipart Form
+
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('formUrlEncoded');
+ }}
+ >
+ Form URL Encoded
+
+ Raw
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('json');
+ }}
+ >
+ JSON
+
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('xml');
+ }}
+ >
+ XML
+
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('text');
+ }}
+ >
+ TEXT
+
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('sparql');
+ }}
+ >
+ SPARQL
+
+ Other
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('file');
+ }}
+ >
+ File / Binary
+
+ {
+ dropdownTippyRef.current.hide();
+ onModeChange('none');
+ }}
+ >
+ No Body
+
{(bodyMode === 'json' || bodyMode === 'xml') && (
diff --git a/packages/bruno-app/src/components/RequestPane/RequestBody/index.js b/packages/bruno-app/src/components/RequestPane/RequestBody/index.js
index d562684e5..fdc674ae6 100644
--- a/packages/bruno-app/src/components/RequestPane/RequestBody/index.js
+++ b/packages/bruno-app/src/components/RequestPane/RequestBody/index.js
@@ -79,4 +79,4 @@ const RequestBody = ({ item, collection }) => {
return No Body;
};
-export default RequestBody;
+export default RequestBody;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RequestPane/RequestHeaders/index.js b/packages/bruno-app/src/components/RequestPane/RequestHeaders/index.js
index ddcc62af2..930a056f9 100644
--- a/packages/bruno-app/src/components/RequestPane/RequestHeaders/index.js
+++ b/packages/bruno-app/src/components/RequestPane/RequestHeaders/index.js
@@ -16,7 +16,7 @@ import BulkEditor from '../../BulkEditor';
const headerAutoCompleteList = StandardHTTPHeaders.map((e) => e.header);
-const RequestHeaders = ({ item, collection }) => {
+const RequestHeaders = ({ item, collection, addHeaderText }) => {
const dispatch = useDispatch();
const { storedTheme } = useTheme();
const headers = item.draft ? get(item, 'draft.request.headers') : get(item, 'request.headers');
@@ -181,7 +181,7 @@ const RequestHeaders = ({ item, collection }) => {
- + Add Header
+ + {addHeaderText || 'Add Header'}
Bulk Edit
diff --git a/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js b/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js
index 7908dfc09..08d011326 100644
--- a/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js
+++ b/packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/index.js
@@ -1,16 +1,13 @@
import { IconLoader2, IconFile, IconAlertTriangle } from '@tabler/icons';
-import { loadRequest, loadRequestViaWorker } from 'providers/ReduxStore/slices/collections/actions';
+import { loadLargeRequest } from 'providers/ReduxStore/slices/collections/actions';
import { useDispatch } from 'react-redux';
import StyledWrapper from './StyledWrapper';
const RequestNotLoaded = ({ collection, item }) => {
const dispatch = useDispatch();
- const handleLoadRequestViaWorker = () => {
- !item?.loading && dispatch(loadRequestViaWorker({ collectionUid: collection?.uid, pathname: item?.pathname }));
- }
- const handleLoadRequest = () => {
- !item?.loading && dispatch(loadRequest({ collectionUid: collection?.uid, pathname: item?.pathname }));
+ const handleLoadLargeRequest = () => {
+ !item?.loading && dispatch(loadLargeRequest({ collectionUid: collection?.uid, pathname: item?.pathname }));
}
return
@@ -44,23 +41,14 @@ const RequestNotLoaded = ({ collection, item }) => {
The request wasn't loaded due to its large size. Please try again with the following options:
-
-
- Load in background
-
- (Runs in background)
-
- Force load
+ Load Request
- (May cause the app to freeze temporarily while it runs)
+ (Uses a regex based parsing approach)
)}
diff --git a/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js b/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js
index 3bee80c40..5349f2410 100644
--- a/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js
+++ b/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js
@@ -18,6 +18,7 @@ const StyledWrapper = styled.div`
padding: 0;
cursor: col-resize;
background: transparent;
+ position: relative;
div.dragbar-handle {
display: flex;
@@ -45,6 +46,7 @@ const StyledWrapper = styled.div`
height: 10px;
cursor: row-resize;
padding: 0 1rem;
+ position: relative;
div.dragbar-handle {
width: 100%;
diff --git a/packages/bruno-app/src/components/RequestTabPanel/index.js b/packages/bruno-app/src/components/RequestTabPanel/index.js
index 6863b30b2..72cd76701 100644
--- a/packages/bruno-app/src/components/RequestTabPanel/index.js
+++ b/packages/bruno-app/src/components/RequestTabPanel/index.js
@@ -4,13 +4,16 @@ import toast from 'react-hot-toast';
import { useSelector, useDispatch } from 'react-redux';
import GraphQLRequestPane from 'components/RequestPane/GraphQLRequestPane';
import HttpRequestPane from 'components/RequestPane/HttpRequestPane';
+import GrpcRequestPane from 'components/RequestPane/GrpcRequestPane/index';
import ResponsePane from 'components/ResponsePane';
+import GrpcResponsePane from 'components/ResponsePane/GrpcResponsePane';
import Welcome from 'components/Welcome';
import { findItemInCollection } from 'utils/collections';
import { updateRequestPaneTabWidth } from 'providers/ReduxStore/slices/tabs';
import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import RequestNotFound from './RequestNotFound';
-import QueryUrl from 'components/RequestPane/QueryUrl';
+import QueryUrl from 'components/RequestPane/QueryUrl/index';
+import GrpcQueryUrl from 'components/RequestPane/GrpcQueryUrl/index';
import NetworkError from 'components/ResponsePane/NetworkError';
import RunnerResults from 'components/RunnerResults';
import VariablesEditor from 'components/VariablesEditor';
@@ -180,6 +183,9 @@ const RequestTabPanel = () => {
return Collection not found! ;
}
+ const item = findItemInCollection(collection, activeTabUid);
+ const isGrpcRequest = item?.type === 'grpc-request';
+
if (focusedTab.type === 'collection-runner') {
return ;
}
@@ -201,7 +207,7 @@ const RequestTabPanel = () => {
if (!folder) {
return ;
}
-
+
return ;
}
@@ -209,20 +215,32 @@ const RequestTabPanel = () => {
return ;
}
- const item = findItemInCollection(collection, activeTabUid);
if (!item || !item.uid) {
return ;
}
if (item?.partial) {
- return
+ return ;
}
if (item?.loading) {
- return
+ return ;
}
const handleRun = async () => {
+ const isGrpcRequest = item?.type === 'grpc-request';
+ const request = item.draft ? item.draft.request : item.request;
+
+ if (isGrpcRequest && !request.url) {
+ toast.error('Please enter a valid gRPC server URL');
+ return;
+ }
+
+ if (isGrpcRequest && !request.method) {
+ toast.error('Please select a gRPC method');
+ return;
+ }
+
dispatch(sendRequest(item, collection.uid)).catch((err) =>
toast.custom((t) => toast.dismiss(t.id)} />, {
duration: 5000
@@ -233,9 +251,13 @@ const RequestTabPanel = () => {
return (
-
+ {isGrpcRequest ? (
+
+ ) : (
+
+ )}
-
+
{
{item.type === 'http-request' ? (
) : null}
+
+ {isGrpcRequest ? (
+
+ ) : null}
@@ -268,7 +294,20 @@ const RequestTabPanel = () => {
-
+ {item.type === 'grpc-request' ? (
+
+ ) : (
+
+ )}
diff --git a/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js b/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js
index 816b00e25..fe574fdaa 100644
--- a/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js
+++ b/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js
@@ -22,6 +22,7 @@ import { flattenItems } from 'utils/collections/index';
const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUid }) => {
const dispatch = useDispatch();
const { storedTheme } = useTheme();
+ const theme = storedTheme === 'dark' ? darkTheme : lightTheme;
const [showConfirmClose, setShowConfirmClose] = useState(false);
const dropdownTippyRef = useRef();
@@ -65,10 +66,10 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi
};
const getMethodColor = (method = '') => {
- const theme = storedTheme === 'dark' ? darkTheme : lightTheme;
return theme.request.methods[method.toLocaleLowerCase()];
};
+
const folder = folderUid ? findItemInCollection(collection, folderUid) : null;
if (['collection-settings', 'collection-overview', 'folder-settings', 'variables', 'collection-runner', 'security-settings'].includes(tab.type)) {
return (
@@ -107,6 +108,7 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi
);
}
+ const isGrpc = item.type === 'grpc-request';
const method = item.draft ? get(item, 'draft.request.method') : get(item, 'request.method');
return (
@@ -159,8 +161,8 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi
}
}}
>
-
- {method}
+
+ {isGrpc ? 'gRPC' : method}
{item.name}
diff --git a/packages/bruno-app/src/components/RequestTabs/index.js b/packages/bruno-app/src/components/RequestTabs/index.js
index d50d528b3..fcba790a6 100644
--- a/packages/bruno-app/src/components/RequestTabs/index.js
+++ b/packages/bruno-app/src/components/RequestTabs/index.js
@@ -18,6 +18,7 @@ const RequestTabs = () => {
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const collections = useSelector((state) => state.collections.collections);
const leftSidebarWidth = useSelector((state) => state.app.leftSidebarWidth);
+ const sidebarCollapsed = useSelector((state) => state.app.sidebarCollapsed);
const screenWidth = useSelector((state) => state.app.screenWidth);
const getTabClassname = (tab, index) => {
@@ -49,7 +50,8 @@ const RequestTabs = () => {
const activeCollection = find(collections, (c) => c.uid === activeTab.collectionUid);
const collectionRequestTabs = filter(tabs, (t) => t.collectionUid === activeTab.collectionUid);
- const maxTablistWidth = screenWidth - leftSidebarWidth - 150;
+ const effectiveSidebarWidth = sidebarCollapsed ? 0 : leftSidebarWidth;
+ const maxTablistWidth = screenWidth - effectiveSidebarWidth - 150;
const tabsWidth = collectionRequestTabs.length * 150 + 34; // 34: (+)icon
const showChevrons = maxTablistWidth < tabsWidth;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcError/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcError/StyledWrapper.js
new file mode 100644
index 000000000..f302b86dd
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcError/StyledWrapper.js
@@ -0,0 +1,44 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ border-left: 4px solid ${(props) => props.theme.colors.text.danger};
+ border-top: 1px solid transparent;
+ border-right: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ border-radius: 0.375rem;
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
+ max-height: 200px;
+ min-height: 70px;
+ overflow-y: auto;
+ background-color: ${(props) => (props.theme.bg === '#1e1e1e' ? 'rgba(40, 40, 40, 0.5)' : 'rgba(250, 250, 250, 0.9)')};
+
+ .close-button {
+ opacity: 0.7;
+ transition: opacity 0.2s;
+
+ &:hover {
+ opacity: 1;
+ }
+
+ svg {
+ color: ${(props) => props.theme.text};
+ }
+ }
+
+ .error-title {
+ font-weight: 600;
+ margin-bottom: 0.375rem;
+ color: ${(props) => props.theme.colors.text.danger};
+ }
+
+ .error-message {
+ font-family: monospace;
+ font-size: 0.6875rem;
+ line-height: 1.25rem;
+ white-space: pre-wrap;
+ word-break: break-all;
+ color: ${(props) => props.theme.text};
+ }
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcError/index.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcError/index.js
new file mode 100644
index 000000000..d2376401d
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcError/index.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import { IconX } from '@tabler/icons';
+import StyledWrapper from './StyledWrapper';
+
+const GrpcError = ({ error, onClose }) => {
+ if (!error) return null;
+
+ return (
+
+
+
+ gRPC Server Error
+ {typeof error === 'string' ? error : JSON.stringify(error, null, 2)}
+
+
+
+
+
+
+ );
+};
+
+export default GrpcError;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcQueryResult/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcQueryResult/StyledWrapper.js
new file mode 100644
index 000000000..81b4c33b1
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcQueryResult/StyledWrapper.js
@@ -0,0 +1,96 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ height: 100%;
+ overflow: hidden;
+ background: ${(props) => props.theme.bg};
+ border-radius: 4px;
+
+ .CodeMirror {
+ height: 100%;
+ font-family: ${(props) => (props.font === 'default' ? 'monospace' : props.font)};
+ font-size: ${(props) => (props.fontSize ? props.fontSize : '13px')};
+ }
+
+ .accordion-header {
+ background-color: ${(props) => props.theme.requestTabPanel.card.bg};
+
+ &:hover {
+ background-color: ${(props) => props.theme.plainGrid.hoverBg};
+ }
+
+ &.open {
+ background-color: ${(props) => props.theme.plainGrid.hoverBg};
+ }
+ }
+
+ .error-header {
+ background-color: ${(props) => (props.theme.bg === '#1e1e1e' ? 'rgba(185, 28, 28, 0.1)' : '#fee2e2')};
+ }
+
+ .error-text {
+ color: ${(props) => props.theme.colors.text.danger};
+ }
+
+ div.tabs {
+ div.tab {
+ padding: 6px 0px;
+ border: none;
+ border-bottom: solid 2px transparent;
+ margin-right: 1.25rem;
+ color: var(--color-tab-inactive);
+ cursor: pointer;
+
+ &:focus,
+ &:active,
+ &:focus-within,
+ &:focus-visible,
+ &:target {
+ outline: none !important;
+ box-shadow: none !important;
+ }
+
+ &.active {
+ color: ${(props) => props.theme.tabs.active.color} !important;
+ border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
+ }
+ }
+ }
+
+ .stream-status {
+ display: inline-flex;
+ align-items: center;
+
+ &.complete {
+ color: ${(props) => props.theme.colors.text.green};
+ }
+
+ &.cancelled {
+ color: ${(props) => props.theme.colors.text.danger};
+ }
+
+ &.streaming {
+ color: ${(props) => props.theme.colors.text.blue};
+ }
+ }
+
+ .message-counter {
+ display: inline-flex;
+ align-items: center;
+ margin-left: 10px;
+ }
+
+ .response-list {
+ max-height: 500px;
+ overflow-y: auto;
+ }
+
+ .response-message {
+ margin-bottom: 8px;
+ padding: 8px;
+ border-radius: 4px;
+ background-color: var(--color-panel-background);
+ }
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcQueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcQueryResult/index.js
new file mode 100644
index 000000000..c6ceeff61
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcQueryResult/index.js
@@ -0,0 +1,126 @@
+import React, { useState, useEffect } from 'react';
+import Accordion from 'components/Accordion';
+import CodeEditor from 'components/CodeEditor';
+import { get } from 'lodash';
+import { useSelector } from 'react-redux';
+import { useTheme } from 'providers/Theme/index';
+import StyledWrapper from './StyledWrapper';
+import { formatISO9075 } from 'date-fns';
+import GrpcError from '../GrpcError';
+
+const GrpcQueryResult = ({ item, collection }) => {
+ const { displayedTheme } = useTheme();
+ const preferences = useSelector((state) => state.app.preferences);
+ const [showErrorMessage, setShowErrorMessage] = useState(true);
+
+ const response = item.response || {};
+ const responsesList = response?.responses || [];
+ // Reverse the responses list to show the most recent at the top
+ const reversedResponsesList = [...responsesList].reverse();
+ const hasError = response.isError;
+ const hasResponses = responsesList.length > 0;
+ const errorMessage = response.error;
+
+ // Reset error visibility when a new response is received
+ useEffect(() => {
+ if (hasError) {
+ setShowErrorMessage(true);
+ }
+ }, [response, hasError]);
+
+ // Format a timestamp to a human-readable format
+ const formatTimestamp = (timestamp) => {
+ if (!timestamp) return 'Unknown time';
+
+ try {
+ const date = new Date(timestamp);
+ return formatISO9075(date);
+ } catch (e) {
+ return 'Invalid time';
+ }
+ };
+
+ // Format JSON for display
+ const formatJSON = (data) => {
+ try {
+ if (typeof data === 'string') {
+ return JSON.stringify(JSON.parse(data), null, 2);
+ }
+ return JSON.stringify(data, null, 2);
+ } catch (e) {
+ return typeof data === 'string' ? data : JSON.stringify(data);
+ }
+ };
+
+ if (!hasResponses && !hasError) {
+ return (
+
+ No messages received
+
+ );
+ }
+
+ return (
+
+ {hasError && showErrorMessage && setShowErrorMessage(false)} />}
+ {hasResponses && (
+
+ {responsesList.length === 1 ? (
+ // Single message - render directly without accordion
+
+
+
+ ) : (
+ // Multiple messages - use accordion
+
+ {reversedResponsesList.map((response, index) => {
+ // Calculate the original response number (for display purposes)
+ const originalIndex = responsesList.length - index - 1;
+
+ return (
+
+
+
+
+ Response {originalIndex + 1} {index === 0 ? '(Latest)' : ''}
+
+
+
+
+
+
+
+
+
+ );
+ })}
+
+ )}
+
+ )}
+ {hasError && !hasResponses && !showErrorMessage && (
+
+ No messages received. A server error occurred but has been dismissed.
+
+ )}
+
+ );
+};
+
+export default GrpcQueryResult;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcResponseHeaders/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcResponseHeaders/StyledWrapper.js
new file mode 100644
index 000000000..d42e77f7f
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcResponseHeaders/StyledWrapper.js
@@ -0,0 +1,31 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ table {
+ width: 100%;
+ border-collapse: collapse;
+
+ thead {
+ color: #777777;
+ font-size: 0.75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
+
+ td {
+ padding: 6px 10px;
+
+ &.value {
+ word-break: break-all;
+ }
+ }
+
+ tbody {
+ tr:nth-child(odd) {
+ background-color: ${(props) => props.theme.table.striped};
+ }
+ }
+ }
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcResponseHeaders/index.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcResponseHeaders/index.js
new file mode 100644
index 000000000..a7390558d
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcResponseHeaders/index.js
@@ -0,0 +1,38 @@
+import React from 'react';
+import StyledWrapper from './StyledWrapper';
+
+const GrpcResponseHeaders = ({ metadata }) => {
+ // Ensure headers is an array
+ const metadataArray = Array.isArray(metadata) ? metadata : [];
+
+ return (
+
+
+
+
+ | Name |
+ Value |
+
+
+
+ {metadataArray && metadataArray.length ? (
+ metadataArray.map((metadata, index) => (
+
+ | {metadata.name} |
+ {metadata.value} |
+
+ ))
+ ) : (
+
+ |
+ No metadata received
+ |
+
+ )}
+
+
+
+ );
+};
+
+export default GrpcResponseHeaders;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/StyledWrapper.js
new file mode 100644
index 000000000..bed367559
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/StyledWrapper.js
@@ -0,0 +1,22 @@
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ font-size: 0.75rem;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+
+ &.text-ok {
+ color: ${(props) => props.theme.requestTabPanel.responseOk};
+ }
+
+ &.text-pending {
+ color: ${(props) => props.theme.requestTabPanel.responsePending};
+ }
+
+ &.text-error {
+ color: ${(props) => props.theme.requestTabPanel.responseError};
+ }
+`;
+
+export default Wrapper;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/get-grpc-status-code-phrase.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/get-grpc-status-code-phrase.js
new file mode 100644
index 000000000..a8c96e645
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/get-grpc-status-code-phrase.js
@@ -0,0 +1,22 @@
+// https://grpc.github.io/grpc/core/md_doc_statuscodes.html
+const grpcStatusCodePhraseMap = {
+ 0: 'OK',
+ 1: 'Cancelled',
+ 2: 'Unknown',
+ 3: 'Invalid Argument',
+ 4: 'Deadline Exceeded',
+ 5: 'Not Found',
+ 6: 'Already Exists',
+ 7: 'Permission Denied',
+ 8: 'Resource Exhausted',
+ 9: 'Failed Precondition',
+ 10: 'Aborted',
+ 11: 'Out of Range',
+ 12: 'Unimplemented',
+ 13: 'Internal',
+ 14: 'Unavailable',
+ 15: 'Data Loss',
+ 16: 'Unauthenticated'
+};
+
+export default grpcStatusCodePhraseMap;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/index.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/index.js
new file mode 100644
index 000000000..af4f10db6
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/GrpcStatusCode/index.js
@@ -0,0 +1,27 @@
+import React from 'react';
+import classnames from 'classnames';
+import grpcStatusCodePhraseMap from './get-grpc-status-code-phrase';
+import StyledWrapper from './StyledWrapper';
+
+const GrpcStatusCode = ({ status, text }) => {
+ // gRPC status codes: 0 is success, anything else is an error
+ const getTabClassname = (status) => {
+ const isPending = text === 'PENDING' || text === 'STREAMING';
+ return classnames('ml-2', {
+ 'text-ok': parseInt(status) === 0,
+ 'text-pending': isPending,
+ 'text-error': parseInt(status) > 0 && !isPending
+ });
+ };
+
+ const statusText = text || grpcStatusCodePhraseMap[status]
+
+ return (
+
+ {Number.isInteger(status) ? {status} : null}
+ {statusText && {statusText} }
+
+ );
+};
+
+export default GrpcStatusCode;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/ResponseTrailers/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/ResponseTrailers/StyledWrapper.js
new file mode 100644
index 000000000..d42e77f7f
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/ResponseTrailers/StyledWrapper.js
@@ -0,0 +1,31 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ table {
+ width: 100%;
+ border-collapse: collapse;
+
+ thead {
+ color: #777777;
+ font-size: 0.75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ }
+
+ td {
+ padding: 6px 10px;
+
+ &.value {
+ word-break: break-all;
+ }
+ }
+
+ tbody {
+ tr:nth-child(odd) {
+ background-color: ${(props) => props.theme.table.striped};
+ }
+ }
+ }
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/ResponseTrailers/index.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/ResponseTrailers/index.js
new file mode 100644
index 000000000..7df1f5b45
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/ResponseTrailers/index.js
@@ -0,0 +1,37 @@
+import React from 'react';
+import StyledWrapper from './StyledWrapper';
+
+const ResponseTrailers = ({ trailers }) => {
+ const trailersArray = Array.isArray(trailers) ? trailers : [];
+
+ return (
+
+
+
+
+ | Name |
+ Value |
+
+
+
+ {trailersArray && trailersArray.length ? (
+ trailersArray.map((trailer, index) => (
+
+ | {trailer.name} |
+ {trailer.value} |
+
+ ))
+ ) : (
+
+ |
+ No trailers received
+ |
+
+ )}
+
+
+
+ );
+};
+
+export default ResponseTrailers;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/StyledWrapper.js
new file mode 100644
index 000000000..e4e358af4
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/StyledWrapper.js
@@ -0,0 +1,58 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ height: 100%;
+ overflow: hidden;
+ background: ${(props) => props.theme.bg};
+ border-radius: 4px;
+
+ div.tabs {
+ div.tab {
+ padding: 6px 0px;
+ border: none;
+ border-bottom: solid 2px transparent;
+ margin-right: 1.25rem;
+ color: var(--color-tab-inactive);
+ cursor: pointer;
+
+ &:focus,
+ &:active,
+ &:focus-within,
+ &:focus-visible,
+ &:target {
+ outline: none !important;
+ box-shadow: none !important;
+ }
+
+ &.active {
+ color: ${(props) => props.theme.tabs.active.color} !important;
+ border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
+ }
+ }
+ }
+
+ .stream-status {
+ display: inline-flex;
+ align-items: center;
+
+ &.complete {
+ color: ${(props) => props.theme.colors.text.green};
+ }
+
+ &.cancelled {
+ color: ${(props) => props.theme.colors.text.danger};
+ }
+
+ &.streaming {
+ color: ${(props) => props.theme.colors.text.blue};
+ }
+ }
+
+ .message-counter {
+ display: inline-flex;
+ align-items: center;
+ margin-left: 10px;
+ }
+`;
+
+export default StyledWrapper;
diff --git a/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/index.js b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/index.js
new file mode 100644
index 000000000..81ab5bc1e
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/GrpcResponsePane/index.js
@@ -0,0 +1,160 @@
+import React, { useState, useEffect } from 'react';
+import find from 'lodash/find';
+import classnames from 'classnames';
+import { useDispatch, useSelector } from 'react-redux';
+import { updateResponsePaneTab } from 'providers/ReduxStore/slices/tabs';
+import Overlay from '../Overlay';
+import Placeholder from '../Placeholder';
+import GrpcResponseHeaders from './GrpcResponseHeaders';
+import GrpcStatusCode from './GrpcStatusCode';
+import ResponseTime from '../ResponseTime/index';
+import Timeline from '../Timeline';
+import ClearTimeline from '../ClearTimeline';
+import ResponseSave from '../ResponseSave';
+import ResponseClear from '../ResponseClear';
+import StyledWrapper from './StyledWrapper';
+import ResponseTrailers from './ResponseTrailers';
+import GrpcQueryResult from './GrpcQueryResult';
+import ResponseLayoutToggle from '../ResponseLayoutToggle';
+import Tab from 'components/Tab';
+
+const GrpcResponsePane = ({ item, collection }) => {
+ const dispatch = useDispatch();
+ const tabs = useSelector((state) => state.tabs.tabs);
+ const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
+ const isLoading = ['queued', 'sending'].includes(item.requestState);
+
+ const requestTimeline = [...(collection?.timeline || [])].filter((obj) => {
+ if (obj.itemUid === item.uid) return true;
+ });
+
+ const selectTab = (tab) => {
+ dispatch(
+ updateResponsePaneTab({
+ uid: item.uid,
+ responsePaneTab: tab
+ })
+ );
+ };
+
+ const response = item.response || {};
+
+ const getTabPanel = (tab) => {
+ switch (tab) {
+ case 'response': {
+ return ;
+ }
+ case 'headers': {
+ return ;
+ }
+ case 'trailers': {
+ return ;
+ }
+ case 'timeline': {
+ return ;
+ }
+ default: {
+ return 404 | Not found ;
+ }
+ }
+ };
+
+ if (isLoading && !item.response) {
+ return (
+
+
+
+ );
+ }
+
+ if (!item.response && !requestTimeline?.length) {
+ return (
+
+
+
+ );
+ }
+
+ if (!activeTabUid) {
+ return Something went wrong ;
+ }
+
+ const focusedTab = find(tabs, (t) => t.uid === activeTabUid);
+ if (!focusedTab || !focusedTab.uid || !focusedTab.responsePaneTab) {
+ return An error occurred! ;
+ }
+
+ const tabConfig = [
+ {
+ name: 'response',
+ label: 'Response',
+ count: Array.isArray(response.responses) ? response.responses.length : 0
+ },
+ {
+ name: 'headers',
+ label: 'Metadata',
+ count: Array.isArray(response.metadata) ? response.metadata.length : 0
+ },
+ {
+ name: 'trailers',
+ label: 'Trailers',
+ count: Array.isArray(response.trailers) ? response.trailers.length : 0
+ },
+ {
+ name: 'timeline',
+ label: 'Timeline'
+ }
+ ];
+
+ return (
+
+
+ {tabConfig.map((tab) => (
+
+ ))}
+ {!isLoading ? (
+
+ {focusedTab?.responsePaneTab === 'timeline' ? (
+ <>
+
+
+ >
+ ) : item?.response ? (
+ <>
+
+
+
+
+ >
+ ) : null}
+
+ ) : null}
+
+
+ {isLoading ? : null}
+ {!item?.response ? (
+ focusedTab?.responsePaneTab === 'timeline' && requestTimeline?.length ? (
+
+ ) : null
+ ) : (
+ <>{getTabPanel(focusedTab.responsePaneTab)}>
+ )}
+
+
+ );
+};
+
+export default GrpcResponsePane;
diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js
index d4fbee07e..595c170e2 100644
--- a/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js
@@ -1,7 +1,9 @@
import React, { useState, useEffect } from 'react';
import CodeEditor from 'components/CodeEditor/index';
import { get } from 'lodash';
+import find from 'lodash/find';
import { useDispatch, useSelector } from 'react-redux';
+import { updateResponsePaneScrollPosition } from 'providers/ReduxStore/slices/tabs';
import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import { Document, Page } from 'react-pdf';
import 'pdfjs-dist/build/pdf.worker';
@@ -51,6 +53,10 @@ const QueryResultPreview = ({
displayedTheme
}) => {
const preferences = useSelector((state) => state.app.preferences);
+ const tabs = useSelector((state) => state.tabs.tabs);
+ const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
+ const focusedTab = find(tabs, (t) => t.uid === activeTabUid);
+
const dispatch = useDispatch();
const [numPages, setNumPages] = useState(null);
@@ -66,9 +72,19 @@ const QueryResultPreview = ({
if (disableRunEventListener) {
return;
}
+
dispatch(sendRequest(item, collection.uid));
};
+ const onScroll = (event) => {
+ dispatch(
+ updateResponsePaneScrollPosition({
+ uid: focusedTab.uid,
+ scrollY: event.doc.scrollTop
+ })
+ );
+ };
+
switch (previewTab?.mode) {
case 'preview-web': {
const webViewSrc = data.replace('', ``);
@@ -111,8 +127,10 @@ const QueryResultPreview = ({
fontSize={get(preferences, 'font.codeFontSize')}
theme={displayedTheme}
onRun={onRun}
+ onScroll={onScroll}
value={formattedData}
mode={mode}
+ initialScroll={focusedTab.responsePaneScrollPosition || 0}
readOnly
/>
);
diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
index a52d1499b..c3e43fd12 100644
--- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js
@@ -80,10 +80,6 @@ const QueryResult = ({ item, collection, data, dataBuffer, disableRunEventListen
const [filter, setFilter] = useState(null);
const [showLargeResponse, setShowLargeResponse] = useState(false);
const responseEncoding = getEncoding(headers);
- const formattedData = useMemo(
- () => formatResponse(data, dataBuffer, responseEncoding, mode, filter),
- [data, dataBuffer, responseEncoding, mode, filter]
- );
const { displayedTheme } = useTheme();
const responseSize = useMemo(() => {
@@ -105,6 +101,16 @@ const QueryResult = ({ item, collection, data, dataBuffer, disableRunEventListen
const isLargeResponse = responseSize > 10 * 1024 * 1024; // 10 MB
+ const formattedData = useMemo(
+ () => {
+ if (isLargeResponse && !showLargeResponse) {
+ return '';
+ }
+ return formatResponse(data, dataBuffer, responseEncoding, mode, filter);
+ },
+ [data, dataBuffer, responseEncoding, mode, filter, isLargeResponse, showLargeResponse]
+ );
+
const debouncedResultFilterOnChange = debounce((e) => {
setFilter(e.target.value);
}, 250);
diff --git a/packages/bruno-app/src/components/ResponsePane/ResponseSize/index.js b/packages/bruno-app/src/components/ResponsePane/ResponseSize/index.js
index b1cff2157..fcdeaaca3 100644
--- a/packages/bruno-app/src/components/ResponsePane/ResponseSize/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/ResponseSize/index.js
@@ -20,7 +20,7 @@ const ResponseSize = ({ size }) => {
}
return (
-
+
{sizeToDisplay}
);
diff --git a/packages/bruno-app/src/components/ResponsePane/ResponseTime/index.js b/packages/bruno-app/src/components/ResponsePane/ResponseTime/index.js
index ed05e944c..52b8b84a3 100644
--- a/packages/bruno-app/src/components/ResponsePane/ResponseTime/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/ResponseTime/index.js
@@ -1,9 +1,9 @@
import React from 'react';
import StyledWrapper from './StyledWrapper';
+import isNumber from 'lodash/isNumber';
const ResponseTime = ({ duration }) => {
let durationToDisplay = '';
-
if (duration > 1000) {
// duration greater than a second
let seconds = Math.floor(duration / 1000);
@@ -13,6 +13,10 @@ const ResponseTime = ({ duration }) => {
durationToDisplay = duration + 'ms';
}
+ if (!isNumber(duration)) {
+ return null;
+ }
+
return {durationToDisplay};
};
export default ResponseTime;
diff --git a/packages/bruno-app/src/components/ResponsePane/Timeline/GrpcTimelineItem/index.js b/packages/bruno-app/src/components/ResponsePane/Timeline/GrpcTimelineItem/index.js
new file mode 100644
index 000000000..5e049118e
--- /dev/null
+++ b/packages/bruno-app/src/components/ResponsePane/Timeline/GrpcTimelineItem/index.js
@@ -0,0 +1,274 @@
+import { useState } from "react";
+import { RelativeTime } from "../TimelineItem/Common/Time/index";
+import Status from "../TimelineItem/Common/Status/index";
+import {
+ IconChevronDown,
+ IconChevronRight,
+ IconServer,
+ IconDatabase,
+ IconAlertCircle,
+ IconCircleCheck,
+ IconCircleX,
+ IconX,
+ IconSend
+} from '@tabler/icons';
+
+// Icons for different event types
+const EventTypeIcons = {
+ metadata: ,
+ response: ,
+ request: ,
+ message: ,
+ status: ,
+ error: ,
+ end: ,
+ cancel:
+};
+
+// Event type display names
+const EventTypeNames = {
+ metadata: "Metadata",
+ response: "Response Message",
+ request: "Request",
+ message: "Message",
+ status: "Status",
+ error: "Error",
+ end: "Stream Ended",
+ cancel: "Cancelled"
+};
+
+// Colors for different event types
+const EventTypeColors = {
+ metadata: "border-blue-500/20",
+ response: "border-green-500/20",
+ request: "border-orange-500/20",
+ message: "border-orange-500/20",
+ status: "border-purple-500/20",
+ error: "border-red-500/20",
+ end: "border-gray-500/20",
+ cancel: "border-amber-500/20"
+};
+
+const GrpcTimelineItem = ({ timestamp, request, response, eventType, eventData, item, collection, width }) => {
+ const [isCollapsed, setIsCollapsed] = useState(true);
+ const toggleCollapse = () => setIsCollapsed(prev => !prev);
+
+ // Use requestSent if available, otherwise fall back to request
+ const effectiveRequest = item.requestSent || request || item.request || {};
+
+ // Extract relevant data from request and response
+ const { method, url = '' } = effectiveRequest;
+ const { statusCode, statusText, duration } = response || {};
+
+ // Get event-specific icon and color
+ const eventIcon = EventTypeIcons[eventType] || ;
+ const eventColor = EventTypeColors[eventType] || "border-gray-500/50";
+ const eventName = EventTypeNames[eventType] || "Event";
+
+
+ // Render appropriate content based on event type
+ const renderEventContent = () => {
+
+ const isClientStreaming = effectiveRequest.methodType === 'client-streaming' || effectiveRequest.methodType === 'bidi-streaming';
+
+ switch(eventType) {
+ case 'request':
+ return (
+
+
+ {effectiveRequest.headers && Object.keys(effectiveRequest.headers).length > 0 && (
+
+ Metadata
+
+ {Object.entries(effectiveRequest.headers).map(([key, value], idx) => (
+
+ ))}
+
+
+ )}
+
+ {/* gRPC Messages section */}
+ {!isClientStreaming && effectiveRequest.body?.mode === 'grpc' && effectiveRequest.body?.grpc?.length > 0 && (
+
+
+ Message
+
+
+ {effectiveRequest.body.grpc.filter((_, index) => index === 0).map((message, idx) => (
+
+
+ {typeof message.content === 'string'
+ ? message.content
+ : JSON.stringify(message.content, null, 2)}
+
+
+ ))}
+
+
+ )}
+
+ );
+
+ case 'message':
+ return (
+
+ Message
+
+ {typeof eventData === 'string'
+ ? eventData
+ : JSON.stringify(eventData, null, 2)}
+
+
+ );
+
+ case 'metadata':
+ return (
+
+ Metadata Headers
+ {response.metadata && response.metadata.length > 0 ? (
+
+ {response.metadata.map((header, idx) => (
+
+ {header.name}:
+ {header.value}
+
+ ))}
+
+ ) : (
+ No metadata headers
+ )}
+
+ );
+
+ case 'response':
+ // For message responses, show the response data
+ return (
+
+
+ Response Message #{(response.responses.length || 0)}
+
+ {response.responses && response.responses.length > 0 ? (
+
+ {JSON.stringify(response.responses[response.responses.length - 1], null, 2)}
+
+ ) : (
+ Empty message
+ )}
+
+ );
+
+ case 'status':
+ // For status events, show status and trailers
+ return (
+
+
+
+
+
+ {response.statusDescription && (
+ {response.statusDescription}
+ )}
+
+ {response.trailers && response.trailers.length > 0 && (
+ <>
+ Trailers
+
+ {response.trailers.map((trailer, idx) => (
+
+ {trailer.name}:
+ {trailer.value || ''}
+
+ ))}
+
+ >
+ )}
+
+ );
+
+ case 'error':
+ // For error events, show error details
+ return (
+
+ Error
+ {response.error || "Unknown error"}
+
+
+
+
+
+ {response.trailers && response.trailers.length > 0 && (
+ <>
+ Error Metadata
+
+ {response.trailers.map((trailer, idx) => (
+
+ {trailer.name}:
+ {trailer.value}
+
+ ))}
+
+ >
+ )}
+
+ );
+
+ case 'end':
+ // For end events, show summary
+ return (
+
+ Stream Ended
+
+ Total messages: {response.responses.length || 0}
+
+
+ );
+
+ case 'cancel':
+ // For cancel events, show cancellation info
+ return (
+
+ Stream Cancelled
+ {response.statusDescription || "The gRPC stream was cancelled"}
+
+ );
+
+ default:
+ return null;
+ }
+ };
+
+ return (
+
+
+ {isCollapsed ? : }
+ {eventIcon}
+ {eventName}
+ {eventType === 'request' && effectiveRequest.methodType && (
+
+ {effectiveRequest.methodType}
+
+ )}
+ {eventType === 'status' && (
+
+
+
+ )}
+ [{new Date(timestamp).toISOString()}]
+
+
+
+
+
+ {/* Always show the URL */}
+ {url}
+
+ {/* Expanded content - only show for non-status items */}
+ {!isCollapsed && renderEventContent()}
+
+ );
+};
+
+export default GrpcTimelineItem;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/ResponsePane/Timeline/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/Timeline/StyledWrapper.js
index 4b7cb28a7..263d45245 100644
--- a/packages/bruno-app/src/components/ResponsePane/Timeline/StyledWrapper.js
+++ b/packages/bruno-app/src/components/ResponsePane/Timeline/StyledWrapper.js
@@ -1,6 +1,15 @@
import styled from 'styled-components';
const StyledWrapper = styled.div`
+ position: relative;
+ overflow-y: auto;
+ height: 100%;
+ flex: 1;
+
+ .timeline-container {
+ flex: 1;
+ }
+
.timeline-event {
padding: 8px 0 0 0;
cursor: pointer;
diff --git a/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js b/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js
index 400f3ffe5..053be2916 100644
--- a/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Request/index.js
@@ -26,7 +26,7 @@ const Request = ({ collection, request, item }) => {
{/* Method and URL */}
{/* Headers */}
diff --git a/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/index.js b/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/index.js
index ff33e41ec..c5fc91295 100644
--- a/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/index.js
@@ -16,7 +16,7 @@ const TimelineItem = ({ timestamp, request, response, item, collection, isOauth2
return (
-
+
diff --git a/packages/bruno-app/src/components/ResponsePane/Timeline/index.js b/packages/bruno-app/src/components/ResponsePane/Timeline/index.js
index 98fe1479a..79bf5725b 100644
--- a/packages/bruno-app/src/components/ResponsePane/Timeline/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/Timeline/index.js
@@ -1,8 +1,9 @@
-import React, { useState } from 'react';
+import React from 'react';
import StyledWrapper from './StyledWrapper';
import { findItemInCollection, findParentItemInCollection } from 'utils/collections/index';
import { get } from 'lodash';
import TimelineItem from './TimelineItem/index';
+import GrpcTimelineItem from './GrpcTimelineItem/index';
const getEffectiveAuthSource = (collection, item) => {
const authMode = item.draft ? get(item, 'draft.request.auth.mode') : get(item, 'request.auth.mode');
@@ -44,9 +45,10 @@ const getEffectiveAuthSource = (collection, item) => {
const Timeline = ({ collection, item }) => {
// Get the effective auth source if auth mode is inherit
const authSource = getEffectiveAuthSource(collection, item);
-
+ const isGrpcRequest = item.type === 'grpc-request';
+
// Filter timeline entries based on new rules
- const combinedTimeline = ([...(collection.timeline || [])]).filter(obj => {
+ const combinedTimeline = ([...(collection?.timeline || [])]).filter(obj => {
// Always show entries for this item
if (obj.itemUid === item.uid) return true;
@@ -57,43 +59,68 @@ const Timeline = ({ collection, item }) => {
}
return false;
- }).sort((a, b) => b.timestamp - a.timestamp);
+ }).sort((a, b) => b.timestamp - a.timestamp)
return (
- {combinedTimeline.map((event, index) => {
- if (event.type === 'request') {
- const { data, timestamp } = event;
- const { request, response } = data;
- return (
-
-
-
- );
- } else if (event.type === 'oauth2') {
- const { data, timestamp } = event;
- const { debugInfo } = data;
- return (
-
-
-
- OAuth2.0 Calls
+ {/* Timeline container with scrollbar */}
+
+ {combinedTimeline.map((event, index) => {
+ // Handle regular requests
+ if (event.type === 'request') {
+
+ const { data, timestamp, eventType } = event;
+ const { request, response, eventData = {}, timestamp: eventTimestamp = timestamp } = data;
+
+ if (isGrpcRequest) {
+ return (
+
+
+ );
+ }
+
+ // Regular HTTP request
+ return (
+
+
+ );
+ }
+ // Handle OAuth2 events
+ else if (event.type === 'oauth2') {
+ const { data, timestamp } = event;
+ const { debugInfo } = data;
+ return (
+
+
{debugInfo && debugInfo.length > 0 ? (
debugInfo.map((data, idx) => (
-
+
{
No debug information available.
)}
-
- );
- }
-
- return null;
- })}
+
+ );
+ }
+
+ return null;
+ })}
+
);
};
diff --git a/packages/bruno-app/src/components/ResponsePane/index.js b/packages/bruno-app/src/components/ResponsePane/index.js
index 22955ac2d..d9147632a 100644
--- a/packages/bruno-app/src/components/ResponsePane/index.js
+++ b/packages/bruno-app/src/components/ResponsePane/index.js
@@ -176,7 +176,7 @@ const ResponsePane = ({ item, collection }) => {
) : null}
{
}
return (
-
+
selectTab('response')}>
Response
@@ -128,7 +127,7 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
-
+
{hasScriptError && showScriptErrorCard && (
props.theme.sidebar.bg};
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ overflow: hidden;
+
+ .header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 1rem;
+ border-bottom: 1px solid ${props => props.theme.sidebar.dragbar};
+ margin-bottom: 0.5rem;
+
+ .counter {
+ font-size: 0.875rem;
+ font-weight: 500;
+ }
+
+ .actions {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ }
+
+ .btn-select-all,
+ .btn-reset {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.75rem;
+ color: ${props => props.theme.textLink};
+ background: none;
+ border: none;
+ padding: 0.25rem 0.5rem;
+ cursor: pointer;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ }
+
+ .request-list {
+ flex: 1;
+ overflow-y: auto;
+
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: ${props => props.theme.console.scrollbarThumb};
+ border-radius: 3px;
+ }
+
+ .loading-message,
+ .empty-message {
+ padding: 0.75rem;
+ color: ${props => props.theme.colors.text.muted};
+ font-size: 0.875rem;
+ }
+
+ .requests-container {
+ padding: 0.5rem;
+ position: relative;
+ }
+ }
+
+ .request-item {
+ display: flex;
+ align-items: center;
+ padding: 0.5rem;
+ border-radius: 4px;
+ margin-bottom: 0.25rem;
+ position: relative;
+ height: 2.5rem;
+ border: 1px solid transparent;
+ background-color: ${props => props.theme.sidebar.bg};
+ transition: transform 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
+
+ &.is-selected {
+ background-color: ${props => props.theme.requestTabs.active.bg};
+ }
+
+ &.is-dragging {
+ opacity: 0.5;
+ background-color: ${props => props.theme.sidebar.bg};
+ border: 1px dashed ${props => props.theme.sidebar.dragbar};
+ transform: scale(0.98);
+ box-shadow: 0 3px 8px rgba(0, 0, 0, 0.12);
+ z-index: 5;
+ }
+
+ &::before,
+ &::after {
+ content: '';
+ position: absolute;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: ${props => props.theme.dragAndDrop?.border || props.theme.textLink};
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s ease;
+ }
+
+ &::before {
+ top: -1px;
+ }
+
+ &::after {
+ bottom: -1px;
+ }
+
+ &.drop-target-above {
+ &::before {
+ opacity: 1;
+ height: 2px;
+ background: ${props => props.theme.dragAndDrop?.border || props.theme.textLink};
+ }
+ }
+
+ &.drop-target-below {
+ &::after {
+ opacity: 1;
+ height: 2px;
+ background: ${props => props.theme.dragAndDrop?.border || props.theme.textLink};
+ }
+ }
+
+ .drag-handle {
+ cursor: grab;
+ margin-right: 0.25rem;
+ color: ${props => props.theme.sidebar.muted};
+ display: flex;
+ align-items: center;
+ transition: color 0.15s ease;
+
+ &:hover {
+ color: ${props => props.theme.text};
+ }
+
+ &:active {
+ cursor: grabbing;
+ color: ${props => props.theme.textLink};
+ }
+ }
+
+ .checkbox-container {
+ cursor: pointer;
+ margin-right: 0.5rem;
+
+ .checkbox {
+ width: 1rem;
+ height: 1rem;
+ border: 1px solid ${props => props.theme.sidebar.dragbar};
+ border-radius: 3px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.1s ease;
+
+ &:hover {
+ border-color: ${props => props.theme.textLink};
+ }
+ }
+ }
+
+ .method {
+ font-family: monospace;
+ font-size: 0.75rem;
+ font-weight: 500;
+ margin-right: 0.5rem;
+ min-width: 3rem;
+ color: ${props => props.theme.sidebar.muted}; // Default color for unknown methods
+
+ &.method-get {
+ color: ${props => props.theme.request.methods.get};
+ }
+
+ &.method-post {
+ color: ${props => props.theme.request.methods.post};
+ }
+
+ &.method-put {
+ color: ${props => props.theme.request.methods.put};
+ }
+
+ &.method-delete {
+ color: ${props => props.theme.request.methods.delete};
+ }
+
+ &.method-patch {
+ color: ${props => props.theme.request.methods.patch};
+ }
+
+ &.method-options {
+ color: ${props => props.theme.request.methods.options};
+ }
+
+ &.method-head {
+ color: ${props => props.theme.request.methods.head};
+ }
+ }
+
+ .request-name {
+ flex: 1;
+ font-size: 0.875rem;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ .folder-path {
+ margin-left: 0.5rem;
+ font-size: 0.75rem;
+ color: ${props => props.theme.sidebar.muted};
+ }
+ }
+ }
+`;
+
+export default StyledWrapper;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx b/packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx
new file mode 100644
index 000000000..aa3a3c9f0
--- /dev/null
+++ b/packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx
@@ -0,0 +1,327 @@
+import React, { useEffect, useState, useCallback, useRef } from 'react';
+import { useDrag, useDrop } from 'react-dnd';
+import { getEmptyImage } from 'react-dnd-html5-backend';
+import { IconGripVertical, IconCheck, IconAdjustmentsAlt } from '@tabler/icons';
+import { useDispatch } from 'react-redux';
+import { updateRunnerConfiguration } from 'providers/ReduxStore/slices/collections/actions';
+import StyledWrapper from './StyledWrapper';
+import { isItemARequest } from 'utils/collections';
+import path from 'utils/common/path';
+import { cloneDeep, get } from 'lodash';
+
+const ItemTypes = {
+ REQUEST_ITEM: 'request-item'
+};
+
+const RequestItem = ({ item, index, moveItem, isSelected, onSelect, onDrop }) => {
+ const ref = useRef(null);
+ const [dropType, setDropType] = useState(null);
+
+ const determineDropType = (monitor) => {
+ const hoverBoundingRect = ref.current?.getBoundingClientRect();
+ const clientOffset = monitor.getClientOffset();
+ if (!hoverBoundingRect || !clientOffset) return null;
+
+ const clientY = clientOffset.y - hoverBoundingRect.top;
+ const middleY = hoverBoundingRect.height / 2;
+
+ return clientY < middleY ? 'above' : 'below';
+ };
+
+ const [{ isDragging }, drag, preview] = useDrag({
+ type: ItemTypes.REQUEST_ITEM,
+ item: { uid: item.uid, name: item.name, request: item.request, index },
+ collect: (monitor) => ({ isDragging: monitor.isDragging() }),
+ options: {
+ dropEffect: "move"
+ },
+ end: (draggedItem, monitor) => {
+ if (monitor.didDrop()) {
+ onDrop();
+ }
+ },
+ });
+
+ const [{ isOver, canDrop }, drop] = useDrop({
+ accept: ItemTypes.REQUEST_ITEM,
+ hover: (draggedItem, monitor) => {
+ if (draggedItem.uid === item.uid) {
+ setDropType(null);
+ return;
+ }
+
+ const dropType = determineDropType(monitor);
+ setDropType(dropType);
+ },
+ drop: (draggedItem, monitor) => {
+ if (draggedItem.uid === item.uid) return;
+
+ const dropType = determineDropType(monitor);
+ let targetIndex = index;
+
+ if (dropType === 'below') {
+ targetIndex = index + 1;
+ }
+
+ if (draggedItem.index < targetIndex) {
+ targetIndex = targetIndex - 1;
+ }
+
+ moveItem(draggedItem.uid, targetIndex);
+ setDropType(null);
+ return { item: draggedItem };
+ },
+ collect: (monitor) => ({
+ isOver: monitor.isOver(),
+ canDrop: monitor.canDrop()
+ }),
+ });
+
+ useEffect(() => {
+ preview(getEmptyImage(), { captureDraggingState: true });
+ }, []);
+
+ // Clear drop type when not hovering
+ useEffect(() => {
+ if (!isOver) {
+ setDropType(null);
+ }
+ }, [isOver]);
+
+ drag(drop(ref));
+
+ const itemClasses = [
+ 'request-item',
+ isDragging ? 'is-dragging' : '',
+ isSelected ? 'is-selected' : '',
+ isOver && canDrop && dropType === 'above' ? 'drop-target-above' : '',
+ isOver && canDrop && dropType === 'below' ? 'drop-target-below' : ''
+ ].filter(Boolean).join(' ');
+
+ return (
+
+
+
+
+
+ onSelect(item)}>
+
+ {isSelected && }
+
+
+
+
+ {item.request?.method.toUpperCase()}
+
+
+
+ {item.name}
+ {item.folderPath && (
+ {item.folderPath}
+ )}
+
+
+ );
+};
+
+const RunConfigurationPanel = ({ collection, selectedItems, setSelectedItems }) => {
+ const dispatch = useDispatch();
+ const [flattenedRequests, setFlattenedRequests] = useState([]);
+ const [originalRequests, setOriginalRequests] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+
+ const flattenRequests = useCallback((collection) => {
+ const result = [];
+
+ const processItems = (items) => {
+ if (!items?.length) return;
+
+ items.forEach(item => {
+ if (isItemARequest(item) && !item.partial) {
+ const relativePath = path.relative(collection.pathname, path.dirname(item.pathname));
+ const folderPath = relativePath !== '.' ? relativePath : '';
+
+ result.push({
+ ...item,
+ folderPath: folderPath.replace(/\\/g, '/')
+ });
+ }
+
+ if (item.items?.length) {
+ processItems(item.items);
+ }
+ });
+ };
+
+ processItems(collection.items);
+ return result;
+ }, []);
+
+ useEffect(() => {
+ setIsLoading(true);
+
+ try {
+ const structureCopy = cloneDeep(collection);
+ const requests = flattenRequests(structureCopy);
+
+ const savedConfiguration = get(collection, 'runnerConfiguration', null);
+ if (savedConfiguration?.requestItemsOrder?.length > 0) {
+ const orderedRequests = [];
+ const requestMap = new Map(requests.map(req => [req.uid, req]));
+
+ savedConfiguration.requestItemsOrder.forEach(uid => {
+ const request = requestMap.get(uid);
+ if (request) {
+ orderedRequests.push(request);
+ requestMap.delete(uid);
+ }
+ });
+
+ requestMap.forEach(request => {
+ orderedRequests.push(request);
+ });
+
+ setFlattenedRequests(orderedRequests);
+ } else {
+ setFlattenedRequests(requests);
+ }
+
+ setOriginalRequests(cloneDeep(requests));
+ } catch (error) {
+ console.error("Error loading collection structure:", error);
+ } finally {
+ setIsLoading(false);
+ }
+ }, [collection, flattenRequests]);
+
+ const moveItem = useCallback((draggedItemUid, hoverIndex) => {
+ setFlattenedRequests((prevRequests) => {
+ const dragIndex = prevRequests.findIndex(item => item.uid === draggedItemUid);
+
+ if (dragIndex === -1 || dragIndex === hoverIndex) {
+ return prevRequests;
+ }
+
+ const updatedRequests = [...prevRequests];
+ const [draggedItem] = updatedRequests.splice(dragIndex, 1);
+ updatedRequests.splice(hoverIndex, 0, draggedItem);
+
+ return updatedRequests;
+ });
+ }, []);
+
+ const handleDrop = useCallback(() => {
+ const selectedUids = new Set(selectedItems);
+
+ setFlattenedRequests(currentRequests => {
+ const newOrderedSelectedUids = currentRequests
+ .filter(item => selectedUids.has(item.uid))
+ .map(item => item.uid);
+
+ const allRequestUidsOrder = currentRequests.map(item => item.uid);
+
+ setSelectedItems(newOrderedSelectedUids);
+ dispatch(updateRunnerConfiguration(collection.uid, newOrderedSelectedUids, allRequestUidsOrder));
+
+ return currentRequests;
+ });
+ }, [selectedItems, collection.uid, dispatch, setSelectedItems]);
+
+ const handleRequestSelect = useCallback((item) => {
+ try {
+ if (selectedItems.includes(item.uid)) {
+ const newSelectedUids = selectedItems.filter(uid => uid !== item.uid);
+ setSelectedItems(newSelectedUids);
+
+ const allRequestUidsOrder = flattenedRequests.map(item => item.uid);
+ dispatch(updateRunnerConfiguration(collection.uid, newSelectedUids, allRequestUidsOrder));
+ } else {
+ const newSelectedUids = [...selectedItems, item.uid];
+
+ const orderedSelectedUids = flattenedRequests
+ .filter(req => newSelectedUids.includes(req.uid))
+ .map(req => req.uid);
+
+ setSelectedItems(orderedSelectedUids);
+
+ const allRequestUidsOrder = flattenedRequests.map(item => item.uid);
+ dispatch(updateRunnerConfiguration(collection.uid, orderedSelectedUids, allRequestUidsOrder));
+ }
+ } catch (error) {
+ console.error("Error selecting item:", error);
+ }
+ }, [selectedItems, setSelectedItems, flattenedRequests, dispatch, collection.uid]);
+
+ const handleSelectAll = useCallback(() => {
+ try {
+ const allRequestUidsOrder = flattenedRequests.map(item => item.uid);
+
+ if (selectedItems.length === flattenedRequests.length) {
+ setSelectedItems([]);
+ dispatch(updateRunnerConfiguration(collection.uid, [], allRequestUidsOrder));
+ } else {
+ setSelectedItems(allRequestUidsOrder);
+ dispatch(updateRunnerConfiguration(collection.uid, allRequestUidsOrder, allRequestUidsOrder));
+ }
+ } catch (error) {
+ console.error("Error selecting/deselecting all items:", error);
+ }
+ }, [flattenedRequests, selectedItems, setSelectedItems, dispatch, collection.uid]);
+
+ const handleReset = useCallback(() => {
+ try {
+ setFlattenedRequests(cloneDeep(originalRequests));
+ setSelectedItems([]);
+ dispatch(updateRunnerConfiguration(collection.uid, [], []));
+ } catch (error) {
+ console.error("Error resetting configuration:", error);
+ }
+ }, [originalRequests, setSelectedItems, collection.uid, dispatch]);
+
+ return (
+
+
+
+ {selectedItems.length} of {flattenedRequests.length} selected
+
+
+
+ {selectedItems.length === flattenedRequests.length ? "Deselect All" : "Select All"}
+
+
+
+ Reset
+
+
+
+
+
+ {isLoading ? (
+ Loading requests...
+ ) : flattenedRequests.length === 0 ? (
+ No requests found in this collection
+ ) : (
+
+ {flattenedRequests.map((item, idx) => {
+ const isSelected = selectedItems.includes(item.uid);
+
+ return (
+ handleRequestSelect(item)}
+ moveItem={moveItem}
+ onDrop={handleDrop}
+ />
+ );
+ })}
+
+ )}
+
+
+ );
+};
+
+export default RunConfigurationPanel;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/RunnerResults/RunnerTags/index.jsx b/packages/bruno-app/src/components/RunnerResults/RunnerTags/index.jsx
index 984452d78..b61b5b9f6 100644
--- a/packages/bruno-app/src/components/RunnerResults/RunnerTags/index.jsx
+++ b/packages/bruno-app/src/components/RunnerResults/RunnerTags/index.jsx
@@ -89,13 +89,15 @@ const RunnerTags = ({ collectionUid, className = '' }) => {
return (
-
setTagsEnabled(!tagsEnabled)}
/>
+
{tagsEnabled && (
diff --git a/packages/bruno-app/src/components/RunnerResults/index.jsx b/packages/bruno-app/src/components/RunnerResults/index.jsx
index f2dbe9d7f..7956eb1ad 100644
--- a/packages/bruno-app/src/components/RunnerResults/index.jsx
+++ b/packages/bruno-app/src/components/RunnerResults/index.jsx
@@ -2,15 +2,17 @@ import React, { useState, useRef, useEffect } from 'react';
import path from 'utils/common/path';
import { useDispatch } from 'react-redux';
import { get, cloneDeep } from 'lodash';
-import { runCollectionFolder, cancelRunnerExecution } from 'providers/ReduxStore/slices/collections/actions';
+import { runCollectionFolder, cancelRunnerExecution, mountCollection, updateRunnerConfiguration } from 'providers/ReduxStore/slices/collections/actions';
import { resetCollectionRunner } from 'providers/ReduxStore/slices/collections';
import { findItemInCollection, getTotalRequestCountInCollection } from 'utils/collections';
-import { IconRefresh, IconCircleCheck, IconCircleX, IconCircleOff, IconCheck, IconX, IconRun } from '@tabler/icons';
+import { IconRefresh, IconCircleCheck, IconCircleX, IconCircleOff, IconCheck, IconX, IconRun, IconLoader2 } from '@tabler/icons';
import ResponsePane from './ResponsePane';
import StyledWrapper from './StyledWrapper';
import { areItemsLoading } from 'utils/collections';
import RunnerTags from './RunnerTags/index';
+import RunConfigurationPanel from './RunConfigurationPanel';
import { getRequestItemsForCollectionRun } from 'utils/collections/index';
+import { updateRunnerTagsDetails } from 'providers/ReduxStore/slices/collections/index';
const getDisplayName = (fullPath, pathname, name = '') => {
let relativePath = path.relative(fullPath, pathname);
@@ -25,25 +27,27 @@ const getTestStatus = (results) => {
};
const allTestsPassed = (item) => {
- return item.status !== 'error' &&
- item.testStatus === 'pass' &&
- item.assertionStatus === 'pass' &&
- item.preRequestTestStatus === 'pass' &&
- item.postResponseTestStatus === 'pass';
+ return item.status !== 'error' &&
+ item.testStatus === 'pass' &&
+ item.assertionStatus === 'pass' &&
+ item.preRequestTestStatus === 'pass' &&
+ item.postResponseTestStatus === 'pass';
};
const anyTestFailed = (item) => {
- return item.status === 'error' ||
- item.testStatus === 'fail' ||
- item.assertionStatus === 'fail' ||
- item.preRequestTestStatus === 'fail' ||
- item.postResponseTestStatus === 'fail';
+ return item.status === 'error' ||
+ item.testStatus === 'fail' ||
+ item.assertionStatus === 'fail' ||
+ item.preRequestTestStatus === 'fail' ||
+ item.postResponseTestStatus === 'fail';
};
export default function RunnerResults({ collection }) {
const dispatch = useDispatch();
const [selectedItem, setSelectedItem] = useState(null);
const [delay, setDelay] = useState(null);
+ const [selectedRequestItems, setSelectedRequestItems] = useState([]);
+ const [configureMode, setConfigureMode] = useState(false);
// ref for the runner output body
const runnerBodyRef = useRef();
@@ -62,6 +66,25 @@ export default function RunnerResults({ collection }) {
autoScrollRunnerBody();
}, [collection, setSelectedItem]);
+ useEffect(() => {
+ const runnerInfo = get(collection, 'runnerResult.info', {});
+ if (runnerInfo.status === 'running') {
+ setConfigureMode(false);
+ }
+ }, [collection.runnerResult]);
+
+ useEffect(() => {
+ const savedConfiguration = get(collection, 'runnerConfiguration', null);
+ if (savedConfiguration) {
+ if (savedConfiguration.selectedRequestItems && configureMode) {
+ setSelectedRequestItems(savedConfiguration.selectedRequestItems);
+ }
+ if (savedConfiguration.delay !== undefined && delay === null) {
+ setDelay(savedConfiguration.delay);
+ }
+ }
+ }, [collection.runnerConfiguration, configureMode, delay]);
+
const collectionCopy = cloneDeep(collection);
const runnerInfo = get(collection, 'runnerResult.info', {});
@@ -93,7 +116,7 @@ export default function RunnerResults({ collection }) {
displayName: getDisplayName(collection.pathname, info.pathname, info.name),
tags: [...(info.request?.tags || [])].sort(),
};
- if (newItem.status !== 'error' && newItem.status !== 'skipped') {
+ if (newItem.status !== 'error' && newItem.status !== 'skipped' && newItem.status !== 'running') {
newItem.testStatus = getTestStatus(newItem.testResults);
newItem.assertionStatus = getTestStatus(newItem.assertionResults);
newItem.preRequestTestStatus = getTestStatus(newItem.preRequestTestResults);
@@ -103,18 +126,41 @@ export default function RunnerResults({ collection }) {
})
.filter(Boolean);
+ const ensureCollectionIsMounted = () => {
+ if(collection.mountStatus === 'mounted'){
+ return;
+ }
+ dispatch(mountCollection({
+ collectionUid: collection.uid,
+ collectionPathname: collection.pathname,
+ brunoConfig: collection.brunoConfig
+ }));
+ };
+
const runCollection = () => {
- dispatch(runCollectionFolder(collection.uid, null, true, Number(delay), tagsEnabled && tags));
+ if (configureMode && selectedRequestItems.length > 0) {
+ dispatch(updateRunnerConfiguration(collection.uid, selectedRequestItems, selectedRequestItems, delay));
+ dispatch(runCollectionFolder(collection.uid, null, true, Number(delay), tagsEnabled && tags, selectedRequestItems));
+ } else {
+ dispatch(updateRunnerConfiguration(collection.uid, [], [], delay));
+ dispatch(runCollectionFolder(collection.uid, null, true, Number(delay), tagsEnabled && tags));
+ }
};
const runAgain = () => {
+ ensureCollectionIsMounted();
+ // Get the saved configuration to determine what to run
+ const savedConfiguration = get(collection, 'runnerConfiguration', null);
+ const savedSelectedItems = savedConfiguration?.selectedRequestItems || [];
+ const savedDelay = savedConfiguration?.delay !== undefined ? savedConfiguration.delay : delay;
dispatch(
runCollectionFolder(
collection.uid,
runnerInfo.folderUid,
- runnerInfo.isRecursive,
- Number(delay),
- tagsEnabled && tags
+ true,
+ Number(savedDelay),
+ tagsEnabled && tags,
+ savedSelectedItems
)
);
};
@@ -125,12 +171,26 @@ export default function RunnerResults({ collection }) {
collectionUid: collection.uid
})
);
+ setSelectedRequestItems([]);
+ setConfigureMode(false);
+ setDelay(null);
};
const cancelExecution = () => {
dispatch(cancelRunnerExecution(runnerInfo.cancelTokenUid));
};
+ const toggleConfigureMode = () => {
+ dispatch(updateRunnerTagsDetails({ collectionUid: collection.uid, tagsEnabled: false }));
+ setConfigureMode(!configureMode);
+ };
+
+ useEffect(() => {
+ if(tagsEnabled) {
+ setConfigureMode(false);
+ }
+ }, [tagsEnabled]);
+
const totalRequestsInCollection = getTotalRequestCountInCollection(collectionCopy);
const passedRequests = items.filter(allTestsPassed);
const failedRequests = items.filter(anyTestFailed);
@@ -142,59 +202,104 @@ export default function RunnerResults({ collection }) {
if (!items || !items.length) {
return (
-
-
- Runner
-
-
-
- You have {totalRequestsInCollection} requests in this collection.
-
- {isCollectionLoading ? Requests in this collection are still loading. : null}
-
-
- setDelay(e.target.value)}
- />
-
+
+
+
+
+ Runner
+
+
+
+ You have {totalRequestsInCollection} requests in this collection.
+ {isCollectionLoading && (
+
+ (Loading...)
+
+ )}
+
+ {isCollectionLoading ? Requests in this collection are still loading. : null}
+
+
+ setDelay(e.target.value)}
+ />
+
- {/* Tags for the collection run */}
-
+ {/* Tags for the collection run */}
+
-
- Run Collection
-
+ {/* Configure requests option */}
+
+
+
+
+
+
-
- Reset
-
+
+
+ {configureMode && selectedRequestItems.length > 0
+ ? `Run ${selectedRequestItems.length} Selected Request${selectedRequestItems.length > 1 ? 's' : ''}`
+ : "Run Collection"
+ }
+
+
+
+ Reset
+
+
+
+
+ {configureMode && (
+
+
+
+ )}
+
);
}
return (
-
-
-
+
+
+
Runner
{runnerInfo.status !== 'ended' && runnerInfo.cancelTokenUid && (
-
+
Cancel Execution
)}
-
+
+
@@ -214,57 +319,59 @@ export default function RunnerResults({ collection }) {
)}
- {runnerInfo?.statusText ?
+ {runnerInfo?.statusText ?
{runnerInfo?.statusText}
- : null}
-
- {items.map((item) => {
- return (
-
-
-
-
- {allTestsPassed(item) ?
-
- : null}
- {item.status === 'skipped' ?
-
- :null}
- {anyTestFailed(item) ?
-
- :null}
-
-
- {item.displayName}
-
- {item.status !== 'error' && item.status !== 'skipped' && item.status !== 'completed' ? (
-
- ) : item.responseReceived?.status ? (
- setSelectedItem(item)}>
- {item.responseReceived?.status}
- -
- {item.responseReceived?.statusText}
-
- ) : (
- setSelectedItem(item)}>
- (request failed)
-
- )}
-
- {tagsEnabled && areTagsAdded && item?.tags?.length > 0 && (
-
- Tags: {item.tags.filter(t => tags.include.includes(t)).join(', ')}
-
- )}
- {item.status == 'error' ? {item.error} : null}
+ : null}
-
+
{runnerInfo.status === 'ended' ? (
@@ -366,15 +475,15 @@ export default function RunnerResults({ collection }) {
{selectedItem.displayName}
- {allTestsPassed(selectedItem) ?
+ {allTestsPassed(selectedItem) ?
- : null}
- {anyTestFailed(selectedItem) ?
-
- : null}
+ : null}
+ {anyTestFailed(selectedItem) ?
+
+ : null}
{selectedItem.status === 'skipped' ?
- : null}
+ : null}
diff --git a/packages/bruno-app/src/components/SensitiveFieldWarning/StyledWrapper.js b/packages/bruno-app/src/components/SensitiveFieldWarning/StyledWrapper.js
new file mode 100644
index 000000000..97a9389d8
--- /dev/null
+++ b/packages/bruno-app/src/components/SensitiveFieldWarning/StyledWrapper.js
@@ -0,0 +1,10 @@
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ .tooltip-mod {
+ font-size: 11px !important;
+ width: 150px !important;
+ }
+`;
+
+export default Wrapper;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/SensitiveFieldWarning/index.js b/packages/bruno-app/src/components/SensitiveFieldWarning/index.js
new file mode 100644
index 000000000..2b2cce326
--- /dev/null
+++ b/packages/bruno-app/src/components/SensitiveFieldWarning/index.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import { IconAlertTriangle } from '@tabler/icons';
+import { Tooltip } from 'react-tooltip';
+import StyledWrapper from './StyledWrapper';
+
+const SensitiveFieldWarning = ({ fieldName, warningMessage }) => {
+ const tooltipId = `sensitive-field-warning-${fieldName}`;
+
+ return (
+
+
+
+
+
+ {warningMessage}
+
+
+ }
+ />
+
+
+ );
+};
+
+export default SensitiveFieldWarning;
diff --git a/packages/bruno-app/src/components/ShareCollection/index.js b/packages/bruno-app/src/components/ShareCollection/index.js
index d0db00905..7fb5fd523 100644
--- a/packages/bruno-app/src/components/ShareCollection/index.js
+++ b/packages/bruno-app/src/components/ShareCollection/index.js
@@ -1,6 +1,6 @@
-import React from 'react';
+import React, { useMemo } from 'react';
import Modal from 'components/Modal';
-import { IconDownload } from '@tabler/icons';
+import { IconDownload, IconLoader2, IconAlertTriangle } from '@tabler/icons';
import StyledWrapper from './StyledWrapper';
import Bruno from 'components/Bruno';
import exportBrunoCollection from 'utils/collections/export';
@@ -8,10 +8,25 @@ import exportPostmanCollection from 'utils/exporters/postman-collection';
import { cloneDeep } from 'lodash';
import { transformCollectionToSaveToExportAsFile } from 'utils/collections/index';
import { useSelector } from 'react-redux';
-import { findCollectionByUid } from 'utils/collections/index';
+import { findCollectionByUid, areItemsLoading } from 'utils/collections/index';
const ShareCollection = ({ onClose, collectionUid }) => {
- const collection = useSelector(state => findCollectionByUid(state.collections.collections, collectionUid));
+ const collection = useSelector((state) => findCollectionByUid(state.collections.collections, collectionUid));
+ const isCollectionLoading = areItemsLoading(collection);
+
+ const hasGrpcRequests = useMemo(() => {
+ const checkItem = (item) => {
+ if (item.type === 'grpc-request') {
+ return true;
+ }
+ if (item.items) {
+ return item.items.some(checkItem);
+ }
+ return false;
+ };
+ return collection?.items?.some(checkItem) || false;
+ }, [collection]);
+
const handleExportBrunoCollection = () => {
const collectionCopy = cloneDeep(collection);
exportBrunoCollection(transformCollectionToSaveToExportAsFile(collectionCopy));
@@ -34,27 +49,55 @@ const ShareCollection = ({ onClose, collectionUid }) => {
hideCancel
>
-
-
-
-
-
-
- Bruno Collection
- Export in Bruno format
-
+
+
+
+ {isCollectionLoading ? : }
-
-
+
+ Bruno Collection
+ {isCollectionLoading ? 'Loading collection...' : 'Export in Bruno format'}
+
+
+
+
+ {hasGrpcRequests && (
+
+
+ Note: gRPC requests in this collection will not be exported
+
+ )}
+
-
+ {isCollectionLoading ? (
+
+ ) : (
+
+ )}
Postman Collection
- Export in Postman format
+
+ {isCollectionLoading ? 'Loading collection...' : 'Export in Postman format'}
+
+
);
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemDragPreview/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemDragPreview/index.js
index 1ad4065a8..fa1fb960b 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemDragPreview/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemDragPreview/index.js
@@ -30,8 +30,9 @@ export const CollectionItemDragPreview = () => {
clientOffset: monitor.getClientOffset(),
}));
if (!isDragging) return null;
+ if (!item.type) return null;
const { x, y } = clientOffset || {};
- const shouldShowFolderIcon = !item.type || item.type === 'folder';
+ const shouldShowFolderIcon = item.type === 'folder';
return (
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js
index aabaafcba..fbef672eb 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index.js
@@ -11,7 +11,7 @@ import {
import { interpolateUrl, interpolateUrlPathParams } from 'utils/url/index';
import { getLanguages } from 'utils/codegenerator/targets';
import { useSelector } from 'react-redux';
-import { getGlobalEnvironmentVariables } from 'utils/collections/index';
+import { getAllVariables, getGlobalEnvironmentVariables } from 'utils/collections/index';
import { resolveInheritedAuth } from './utils/auth-utils';
const GenerateCodeItem = ({ collectionUid, item, onClose }) => {
@@ -37,12 +37,13 @@ const GenerateCodeItem = ({ collectionUid, item, onClose }) => {
const requestUrl =
get(item, 'draft.request.url') !== undefined ? get(item, 'draft.request.url') : get(item, 'request.url');
+ const variables = useMemo(() => {
+ return getAllVariables({ ...collection, globalEnvironmentVariables }, item);
+ }, [collection, globalEnvironmentVariables, item]);
+
const interpolatedUrl = interpolateUrl({
url: requestUrl,
- globalEnvironmentVariables,
- envVars,
- runtimeVariables: collection.runtimeVariables,
- processEnvVars: collection.processEnvVariables
+ variables
});
// interpolate the path params
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/interpolation.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/interpolation.js
index 22a52f84f..e7081b268 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/interpolation.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/interpolation.js
@@ -69,24 +69,3 @@ export const interpolateBody = (body, variables = {}) => {
return interpolatedBody;
};
-
-export const createVariablesObject = ({
- globalEnvironmentVariables = {},
- collectionVars = {},
- allVariables = {},
- collection = {},
- runtimeVariables = {},
- processEnvVars = {}
-}) => {
- return {
- ...globalEnvironmentVariables,
- ...allVariables,
- ...collectionVars,
- ...runtimeVariables,
- process: {
- env: {
- ...processEnvVars
- }
- }
- };
-};
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.js
index 60f181ed1..41d9236ed 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.js
@@ -1,7 +1,7 @@
import { buildHarRequest } from 'utils/codegenerator/har';
import { getAuthHeaders } from 'utils/codegenerator/auth';
import { getAllVariables, getTreePathFromCollectionToItem } from 'utils/collections/index';
-import { interpolateHeaders, interpolateBody, createVariablesObject } from './interpolation';
+import { interpolateHeaders, interpolateBody } from './interpolation';
// Merge headers from collection, folders, and request
const mergeHeaders = (collection, request, requestTreePath) => {
@@ -46,17 +46,7 @@ const generateSnippet = ({ language, item, collection, shouldInterpolate = false
// Get HTTPSnippet dynamically so mocks can be applied in tests
const { HTTPSnippet } = require('httpsnippet');
- const allVariables = getAllVariables(collection, item);
-
- // Create variables object for interpolation
- const variables = createVariablesObject({
- globalEnvironmentVariables: collection.globalEnvironmentVariables || {},
- collectionVars: collection.collectionVars || {},
- allVariables,
- collection,
- runtimeVariables: collection.runtimeVariables || {},
- processEnvVars: collection.processEnvVariables || {}
- });
+ const variables = getAllVariables(collection, item);
const request = item.request;
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.spec.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.spec.js
index 941ea7a76..43581b2b4 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.spec.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/utils/snippet-generator.spec.js
@@ -46,7 +46,10 @@ jest.mock('utils/codegenerator/auth', () => ({
}));
jest.mock('utils/collections/index', () => ({
- getAllVariables: jest.fn(() => ({
+ getAllVariables: jest.fn((collection) => ({
+ ...collection?.globalEnvironmentVariables,
+ ...collection?.runtimeVariables,
+ ...collection?.processEnvVariables,
baseUrl: 'https://api.example.com',
apiKey: 'secret-key-123',
userId: '12345'
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/StyledWrapper.js
index bdb62e843..04d338d5e 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/StyledWrapper.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/StyledWrapper.js
@@ -34,6 +34,9 @@ const Wrapper = styled.div`
.method-head {
color: ${(props) => props.theme.request.methods.head};
}
+ .method-grpc {
+ color: ${(props) => props.theme.request.grpc};
+ }
`;
export default Wrapper;
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/index.js
index e41309871..73cfc50ed 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/index.js
@@ -3,10 +3,12 @@ import classnames from 'classnames';
import StyledWrapper from './StyledWrapper';
const RequestMethod = ({ item }) => {
- if (!['http-request', 'graphql-request'].includes(item.type)) {
+ if (!['http-request', 'graphql-request', 'grpc-request'].includes(item.type)) {
return null;
}
+ const isGrpc = item.type === 'grpc-request';
+
const getClassname = (method = '') => {
method = method.toLocaleLowerCase();
return classnames('mr-1', {
@@ -16,7 +18,8 @@ const RequestMethod = ({ item }) => {
'method-delete': method === 'delete',
'method-patch': method === 'patch',
'method-head': method === 'head',
- 'method-options': method == 'options'
+ 'method-options': method === 'options',
+ 'method-grpc': isGrpc,
});
};
@@ -24,7 +27,7 @@ const RequestMethod = ({ item }) => {
- {item.request.method.length > 5 ? item.request.method.substring(0, 3) : item.request.method}
+ {isGrpc ? 'grpc' : item.request.method.length > 5 ? item.request.method.substring(0, 3) : item.request.method}
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js
index a20de70ea..e7a3a21ea 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js
@@ -217,6 +217,12 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
);
};
+ // prevent the parent's double-click handler from firing
+ const handleFolderDoubleClick = (e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ };
+
const handleRightClick = (event) => {
const _menuDropdown = dropdownTippyRef.current;
if (_menuDropdown) {
@@ -358,6 +364,7 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
className={iconClassName}
style={{ color: 'rgb(160 160 160)' }}
onClick={handleFolderCollapse}
+ onDoubleClick={handleFolderDoubleClick}
/>
) : null}
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js
index 404258d8d..0f44b467a 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js
@@ -61,13 +61,14 @@ const Collection = ({ collection, searchText }) => {
};
const ensureCollectionIsMounted = () => {
- if (collection.mountStatus === 'unmounted') {
- dispatch(mountCollection({
- collectionUid: collection.uid,
- collectionPathname: collection.pathname,
- brunoConfig: collection.brunoConfig
- }));
+ if(collection.mountStatus === 'mounted'){
+ return;
}
+ dispatch(mountCollection({
+ collectionUid: collection.uid,
+ collectionPathname: collection.pathname,
+ brunoConfig: collection.brunoConfig
+ }));
}
const hasSearchText = searchText && searchText?.trim()?.length;
@@ -111,6 +112,12 @@ const Collection = ({ collection, searchText }) => {
dispatch(toggleCollection(collection.uid));
}
+ // prevent the parent's double-click handler from firing
+ const handleCollectionDoubleClick = (e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ };
+
const handleRightClick = (event) => {
const _menuDropdown = menuDropdownTippyRef.current;
if (_menuDropdown) {
@@ -223,6 +230,7 @@ const Collection = ({ collection, searchText }) => {
className={`chevron-icon ${iconClassName}`}
style={{ width: 16, minWidth: 16, color: 'rgb(160 160 160)' }}
onClick={handleCollectionCollapse}
+ onDoubleClick={handleCollectionDoubleClick}
/>
|