mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-23 04:35:40 +00:00
feat: collection-level and app-level proxy settings updates (#6514)
* feat: collection and app proxy settings updates * fix: opencollection proxy config export and import * fix: coderabbit review fixes
This commit is contained in:
189
package-lock.json
generated
189
package-lock.json
generated
@@ -26,7 +26,6 @@
|
||||
"@eslint/compat": "^1.3.2",
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@jest/globals": "^29.2.0",
|
||||
"@opencollection/types": "0.3.0",
|
||||
"@playwright/test": "^1.51.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@storybook/addon-webpack5-compiler-babel": "^4.0.0",
|
||||
@@ -1604,7 +1603,7 @@
|
||||
"version": "7.26.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
|
||||
"integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.25.9",
|
||||
@@ -1622,7 +1621,7 @@
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
|
||||
"integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.22.6",
|
||||
@@ -1639,7 +1638,7 @@
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
@@ -1657,7 +1656,7 @@
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@babel/helper-globals": {
|
||||
@@ -1737,7 +1736,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
|
||||
"integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.25.9",
|
||||
@@ -1812,7 +1811,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
|
||||
"integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.25.9",
|
||||
@@ -1855,7 +1854,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
|
||||
"integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -1872,7 +1871,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
|
||||
"integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -1888,7 +1887,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
|
||||
"integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -1904,7 +1903,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
|
||||
"integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -1922,7 +1921,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
|
||||
"integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -1957,7 +1956,7 @@
|
||||
"version": "7.21.0-placeholder-for-preset-env.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
|
||||
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -2056,7 +2055,7 @@
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
|
||||
"integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2072,7 +2071,7 @@
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
|
||||
"integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2254,7 +2253,7 @@
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
|
||||
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
|
||||
@@ -2271,7 +2270,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
|
||||
"integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2287,7 +2286,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
|
||||
"integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -2305,7 +2304,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
|
||||
"integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.25.9",
|
||||
@@ -2323,7 +2322,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz",
|
||||
"integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2339,7 +2338,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
|
||||
"integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2371,7 +2370,7 @@
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
|
||||
"integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.25.9",
|
||||
@@ -2388,7 +2387,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
|
||||
"integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.25.9",
|
||||
@@ -2409,7 +2408,7 @@
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -2419,7 +2418,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
|
||||
"integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -2436,7 +2435,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
|
||||
"integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2452,7 +2451,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -2469,7 +2468,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
|
||||
"integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2485,7 +2484,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -2502,7 +2501,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
|
||||
"integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2518,7 +2517,7 @@
|
||||
"version": "7.26.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
|
||||
"integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2534,7 +2533,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
|
||||
"integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2566,7 +2565,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
|
||||
"integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -2583,7 +2582,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
|
||||
"integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.25.9",
|
||||
@@ -2601,7 +2600,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
|
||||
"integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2617,7 +2616,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
|
||||
"integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2633,7 +2632,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
|
||||
"integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2649,7 +2648,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
|
||||
"integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2665,7 +2664,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
|
||||
"integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.25.9",
|
||||
@@ -2698,7 +2697,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
|
||||
"integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.25.9",
|
||||
@@ -2717,7 +2716,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
|
||||
"integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.25.9",
|
||||
@@ -2734,7 +2733,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -2751,7 +2750,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
|
||||
"integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2782,7 +2781,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
|
||||
"integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2798,7 +2797,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
|
||||
"integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.25.9",
|
||||
@@ -2816,7 +2815,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
|
||||
"integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -2833,7 +2832,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
|
||||
"integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2865,7 +2864,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
|
||||
"integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -2897,7 +2896,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
|
||||
"integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.25.9",
|
||||
@@ -2915,7 +2914,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
|
||||
"integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3000,7 +2999,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
|
||||
"integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -3017,7 +3016,7 @@
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
|
||||
"integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -3034,7 +3033,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
|
||||
"integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3050,7 +3049,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
|
||||
"integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3066,7 +3065,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
|
||||
"integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9",
|
||||
@@ -3083,7 +3082,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3099,7 +3098,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
|
||||
"integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3115,7 +3114,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
|
||||
"integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3150,7 +3149,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
|
||||
"integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.25.9"
|
||||
@@ -3166,7 +3165,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -3183,7 +3182,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -3200,7 +3199,7 @@
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
|
||||
"integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
|
||||
@@ -3217,7 +3216,7 @@
|
||||
"version": "7.26.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz",
|
||||
"integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.26.0",
|
||||
@@ -3318,7 +3317,7 @@
|
||||
"version": "0.1.6-no-external-plugins",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
|
||||
"integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.0.0",
|
||||
@@ -6097,9 +6096,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@opencollection/types": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@opencollection/types/-/types-0.3.0.tgz",
|
||||
"integrity": "sha512-kw+co3sM4ATDQI85lgy5UmOilEHFVdNYvOjZXmnSw6PUDUTAGBiaZNdwdSXwp//o4IwKbTQb8/0I3UdjLKh+qA==",
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@opencollection/types/-/types-0.5.0.tgz",
|
||||
"integrity": "sha512-9rpu5agMrMLcMVU2UgyV+PYV3Zf/sHBJDHMQoq8XiMEUH8lt9f7yGtlerm/9dS3SHMpGX4A8ik0OFtc0dX4r1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -9547,6 +9546,7 @@
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
||||
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
@@ -9566,6 +9566,7 @@
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -9578,6 +9579,7 @@
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
||||
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
@@ -9592,6 +9594,7 @@
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@testing-library/jest-dom": {
|
||||
@@ -9702,6 +9705,7 @@
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
@@ -9994,6 +9998,7 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
@@ -10016,6 +10021,7 @@
|
||||
"version": "12.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
|
||||
"integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "*",
|
||||
@@ -10026,6 +10032,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
@@ -11400,6 +11407,7 @@
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
@@ -11844,7 +11852,7 @@
|
||||
"version": "0.4.12",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
|
||||
"integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.22.6",
|
||||
@@ -11859,7 +11867,7 @@
|
||||
"version": "0.10.6",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
|
||||
"integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-define-polyfill-provider": "^0.6.2",
|
||||
@@ -11873,7 +11881,7 @@
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
|
||||
"integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-define-polyfill-provider": "^0.6.3"
|
||||
@@ -13763,7 +13771,7 @@
|
||||
"version": "3.39.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
|
||||
"integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.24.2"
|
||||
@@ -14912,6 +14920,7 @@
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dom-converter": {
|
||||
@@ -15984,7 +15993,7 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -18860,7 +18869,7 @@
|
||||
"version": "2.16.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
|
||||
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.2"
|
||||
@@ -21317,6 +21326,7 @@
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
||||
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"lz-string": "bin/bin.js"
|
||||
@@ -22931,7 +22941,7 @@
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
@@ -25458,14 +25468,14 @@
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
|
||||
"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/regenerate-unicode-properties": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
|
||||
"integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"regenerate": "^1.4.2"
|
||||
@@ -25484,7 +25494,7 @@
|
||||
"version": "0.15.2",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
|
||||
"integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.4"
|
||||
@@ -25494,7 +25504,7 @@
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz",
|
||||
"integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"regenerate": "^1.4.2",
|
||||
@@ -25512,14 +25522,14 @@
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
|
||||
"integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/regjsparser": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
|
||||
"integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"jsesc": "~3.0.2"
|
||||
@@ -25532,7 +25542,7 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
|
||||
"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jsesc": "bin/jsesc"
|
||||
@@ -25728,7 +25738,7 @@
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
|
||||
"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.16.0",
|
||||
@@ -28046,7 +28056,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -29233,7 +29243,7 @@
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
@@ -29294,7 +29304,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
|
||||
"integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -29304,7 +29314,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
|
||||
"integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"unicode-canonical-property-names-ecmascript": "^2.0.0",
|
||||
@@ -29318,7 +29328,7 @@
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
|
||||
"integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -29328,7 +29338,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
|
||||
"integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
@@ -33603,7 +33613,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.4",
|
||||
"@opencollection/types": "0.3.0",
|
||||
"@opencollection/types": "~0.5.0",
|
||||
"@rollup/plugin-alias": "^5.1.0",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
@@ -35249,6 +35259,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.0",
|
||||
"@babel/preset-typescript": "^7.22.0",
|
||||
"@opencollection/types": "~0.5.0",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
|
||||
13
package.json
13
package.json
@@ -20,17 +20,15 @@
|
||||
],
|
||||
"homepage": "https://usebruno.com",
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.3.2",
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@jest/globals": "^29.2.0",
|
||||
"@playwright/test": "^1.51.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@storybook/addon-webpack5-compiler-babel": "^4.0.0",
|
||||
"@storybook/builder-webpack5": "^10.1.10",
|
||||
"@storybook/react": "^10.1.10",
|
||||
"@storybook/react-webpack5": "^10.1.10",
|
||||
"storybook": "^10.1.10",
|
||||
"@eslint/compat": "^1.3.2",
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@jest/globals": "^29.2.0",
|
||||
"@opencollection/types": "0.3.0",
|
||||
"@playwright/test": "^1.51.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@stylistic/eslint-plugin": "^5.3.1",
|
||||
"@types/jest": "^29.5.11",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
@@ -49,6 +47,7 @@
|
||||
"pretty-quick": "^3.1.3",
|
||||
"randomstring": "^1.2.2",
|
||||
"rimraf": "^6.0.1",
|
||||
"storybook": "^10.1.10",
|
||||
"ts-jest": "^29.2.6"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -12,7 +12,19 @@ import Button from 'ui/Button';
|
||||
|
||||
const ProxySettings = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const initialProxyConfig = { enabled: 'global', protocol: 'http', hostname: '', port: '', auth: { enabled: false, username: '', password: '' }, bypassProxy: '' };
|
||||
const initialProxyConfig = {
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: '',
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
// Get proxy from draft.brunoConfig if it exists, otherwise from brunoConfig
|
||||
const currentProxyConfig = collection.draft?.brunoConfig
|
||||
@@ -82,34 +94,57 @@ const ProxySettings = ({ collection }) => {
|
||||
|
||||
const handleEnabledChange = (e) => {
|
||||
const value = e.target.value;
|
||||
// Convert string to boolean or keep as 'global'
|
||||
const enabled = value === 'true' ? true : value === 'false' ? false : 'global';
|
||||
updateProxy({ enabled });
|
||||
// Map UI values to new format
|
||||
if (value === 'inherit') {
|
||||
updateProxy({ disabled: false, inherit: true });
|
||||
} else if (value === 'true') {
|
||||
updateProxy({ disabled: false, inherit: false });
|
||||
} else {
|
||||
updateProxy({ disabled: true, inherit: false });
|
||||
}
|
||||
};
|
||||
|
||||
const handleProtocolChange = (e) => {
|
||||
updateProxy({ protocol: e.target.value });
|
||||
updateProxy({
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
protocol: e.target.value
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleHostnameChange = (e) => {
|
||||
const hostname = e.target.value;
|
||||
if (validateHostnameOnChange(hostname)) {
|
||||
updateProxy({ hostname });
|
||||
updateProxy({
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
hostname
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handlePortChange = (e) => {
|
||||
const port = e.target.value ? Number(e.target.value) : '';
|
||||
if (validatePortOnChange(port)) {
|
||||
updateProxy({ port });
|
||||
updateProxy({
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
port
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleAuthEnabledChange = (e) => {
|
||||
updateProxy({
|
||||
auth: {
|
||||
...currentProxyConfig.auth,
|
||||
enabled: e.target.checked
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
auth: {
|
||||
...currentProxyConfig.config.auth,
|
||||
disabled: !e.target.checked
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -118,9 +153,12 @@ const ProxySettings = ({ collection }) => {
|
||||
const username = e.target.value;
|
||||
if (validateAuthUsernameOnChange(username)) {
|
||||
updateProxy({
|
||||
auth: {
|
||||
...currentProxyConfig.auth,
|
||||
username
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
auth: {
|
||||
...currentProxyConfig.config.auth,
|
||||
username
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -130,9 +168,12 @@ const ProxySettings = ({ collection }) => {
|
||||
const password = e.target.value;
|
||||
if (validateAuthPasswordOnChange(password)) {
|
||||
updateProxy({
|
||||
auth: {
|
||||
...currentProxyConfig.auth,
|
||||
password
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
auth: {
|
||||
...currentProxyConfig.config.auth,
|
||||
password
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -141,11 +182,19 @@ const ProxySettings = ({ collection }) => {
|
||||
const handleBypassProxyChange = (e) => {
|
||||
const bypassProxy = e.target.value;
|
||||
if (validateBypassProxyOnChange(bypassProxy)) {
|
||||
updateProxy({ bypassProxy });
|
||||
updateProxy({
|
||||
config: {
|
||||
...currentProxyConfig.config,
|
||||
bypassProxy
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const enabledValue = currentProxyConfig.enabled === true ? 'true' : currentProxyConfig.enabled === false ? 'false' : 'global';
|
||||
// Map new format to UI values
|
||||
const disabled = currentProxyConfig.disabled || false;
|
||||
const inherit = currentProxyConfig.inherit !== undefined ? currentProxyConfig.inherit : true;
|
||||
const enabledValue = disabled ? 'false' : (inherit ? 'inherit' : 'true');
|
||||
|
||||
return (
|
||||
<StyledWrapper className="h-full w-full">
|
||||
@@ -157,9 +206,9 @@ const ProxySettings = ({ collection }) => {
|
||||
<InfoTip infotipId="request-var">
|
||||
<div>
|
||||
<ul>
|
||||
<li><span style={{ width: '50px', display: 'inline-block' }}>global</span> - use global proxy config</li>
|
||||
<li><span style={{ width: '50px', display: 'inline-block' }}>enabled</span> - use collection proxy config</li>
|
||||
<li><span style={{ width: '50px', display: 'inline-block' }}>disable</span> - disable proxy</li>
|
||||
<li><span style={{ width: '50px', display: 'inline-block' }}>inherit</span> - inherit from global preferences</li>
|
||||
<li><span style={{ width: '50px', display: 'inline-block' }}>enabled</span> - use collection-specific proxy config</li>
|
||||
<li><span style={{ width: '50px', display: 'inline-block' }}>disabled</span> - disable proxy for this collection</li>
|
||||
</ul>
|
||||
</div>
|
||||
</InfoTip>
|
||||
@@ -169,12 +218,12 @@ const ProxySettings = ({ collection }) => {
|
||||
<input
|
||||
type="radio"
|
||||
name="enabled"
|
||||
value="global"
|
||||
checked={enabledValue === 'global'}
|
||||
value="inherit"
|
||||
checked={enabledValue === 'inherit'}
|
||||
onChange={handleEnabledChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
global
|
||||
inherit
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
@@ -200,164 +249,168 @@ const ProxySettings = ({ collection }) => {
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="protocol">
|
||||
Protocol
|
||||
</label>
|
||||
<div className="flex items-center">
|
||||
<label className="flex items-center">
|
||||
{enabledValue === 'true' && (
|
||||
<>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="protocol">
|
||||
Protocol
|
||||
</label>
|
||||
<div className="flex items-center">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="http"
|
||||
checked={(currentProxyConfig.config?.protocol || 'http') === 'http'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
HTTP
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="https"
|
||||
checked={(currentProxyConfig.config?.protocol || 'http') === 'https'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
HTTPS
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="socks4"
|
||||
checked={(currentProxyConfig.config?.protocol || 'http') === 'socks4'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
SOCKS4
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="socks5"
|
||||
checked={(currentProxyConfig.config?.protocol || 'http') === 'socks5'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
SOCKS5
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="hostname">
|
||||
Hostname
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="http"
|
||||
checked={(currentProxyConfig.protocol || 'http') === 'http'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
HTTP
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="https"
|
||||
checked={(currentProxyConfig.protocol || 'http') === 'https'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
HTTPS
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="socks4"
|
||||
checked={(currentProxyConfig.protocol || 'http') === 'socks4'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
SOCKS4
|
||||
</label>
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
value="socks5"
|
||||
checked={(currentProxyConfig.protocol || 'http') === 'socks5'}
|
||||
onChange={handleProtocolChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
SOCKS5
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="hostname">
|
||||
Hostname
|
||||
</label>
|
||||
<input
|
||||
id="hostname"
|
||||
type="text"
|
||||
name="hostname"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={handleHostnameChange}
|
||||
value={currentProxyConfig.hostname || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="port">
|
||||
Port
|
||||
</label>
|
||||
<input
|
||||
id="port"
|
||||
type="number"
|
||||
name="port"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={handlePortChange}
|
||||
value={currentProxyConfig.port || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.enabled">
|
||||
Auth
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="auth.enabled"
|
||||
checked={currentProxyConfig.auth?.enabled || false}
|
||||
onChange={handleAuthEnabledChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.username">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
id="auth.username"
|
||||
type="text"
|
||||
name="auth.username"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={currentProxyConfig.auth?.username || ''}
|
||||
onChange={handleAuthUsernameChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.password">
|
||||
Password
|
||||
</label>
|
||||
<div className="textbox flex flex-row items-center w-[13.2rem] h-[1.70rem] relative">
|
||||
<input
|
||||
id="auth.password"
|
||||
type={passwordVisible ? 'text' : 'password'}
|
||||
name="auth.password"
|
||||
className="outline-none bg-transparent w-[10.5rem]"
|
||||
id="hostname"
|
||||
type="text"
|
||||
name="hostname"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={currentProxyConfig.auth?.password || ''}
|
||||
onChange={handleAuthPasswordChange}
|
||||
onChange={handleHostnameChange}
|
||||
value={currentProxyConfig.config?.hostname || ''}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm absolute right-0"
|
||||
onClick={() => setPasswordVisible(!passwordVisible)}
|
||||
>
|
||||
{passwordVisible ? <IconEyeOff size={18} strokeWidth={1.5} /> : <IconEye size={18} strokeWidth={1.5} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="bypassProxy">
|
||||
Proxy Bypass
|
||||
</label>
|
||||
<input
|
||||
id="bypassProxy"
|
||||
type="text"
|
||||
name="bypassProxy"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={handleBypassProxyChange}
|
||||
value={currentProxyConfig.bypassProxy || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="port">
|
||||
Port
|
||||
</label>
|
||||
<input
|
||||
id="port"
|
||||
type="number"
|
||||
name="port"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={handlePortChange}
|
||||
value={currentProxyConfig.config?.port || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.disabled">
|
||||
Auth
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="auth.disabled"
|
||||
checked={!currentProxyConfig.config?.auth?.disabled}
|
||||
onChange={handleAuthEnabledChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.username">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
id="auth.username"
|
||||
type="text"
|
||||
name="auth.username"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={currentProxyConfig.config?.auth?.username || ''}
|
||||
onChange={handleAuthUsernameChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.password">
|
||||
Password
|
||||
</label>
|
||||
<div className="textbox flex flex-row items-center w-[13.2rem] h-[1.70rem] relative">
|
||||
<input
|
||||
id="auth.password"
|
||||
type={passwordVisible ? 'text' : 'password'}
|
||||
name="auth.password"
|
||||
className="outline-none bg-transparent w-[10.5rem]"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={currentProxyConfig.config?.auth?.password || ''}
|
||||
onChange={handleAuthPasswordChange}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm absolute right-0"
|
||||
onClick={() => setPasswordVisible(!passwordVisible)}
|
||||
>
|
||||
{passwordVisible ? <IconEyeOff size={18} strokeWidth={1.5} /> : <IconEye size={18} strokeWidth={1.5} />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="bypassProxy">
|
||||
Proxy Bypass
|
||||
</label>
|
||||
<input
|
||||
id="bypassProxy"
|
||||
type="text"
|
||||
name="bypassProxy"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={handleBypassProxyChange}
|
||||
value={currentProxyConfig.config?.bypassProxy || ''}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="mt-6">
|
||||
<Button type="submit" size="sm" onClick={handleSave}>
|
||||
Save
|
||||
|
||||
@@ -18,56 +18,41 @@ const ProxySettings = ({ close }) => {
|
||||
console.log(preferences);
|
||||
|
||||
const proxySchema = Yup.object({
|
||||
mode: Yup.string().oneOf(['off', 'on', 'system']),
|
||||
protocol: Yup.string().required().oneOf(['http', 'https', 'socks4', 'socks5']),
|
||||
hostname: Yup.string()
|
||||
.when('enabled', {
|
||||
is: 'on',
|
||||
then: (hostname) => hostname.required('Specify the hostname for your proxy.'),
|
||||
otherwise: (hostname) => hostname.nullable()
|
||||
})
|
||||
.max(1024),
|
||||
port: Yup.number()
|
||||
.min(1)
|
||||
.max(65535)
|
||||
.typeError('Specify port between 1 and 65535')
|
||||
.nullable()
|
||||
.transform((_, val) => (val ? Number(val) : null)),
|
||||
auth: Yup.object()
|
||||
.when('enabled', {
|
||||
is: 'on',
|
||||
then: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
username: Yup.string()
|
||||
.when(['enabled'], {
|
||||
is: true,
|
||||
then: (username) => username.required('Specify username for proxy authentication.')
|
||||
})
|
||||
.max(1024),
|
||||
password: Yup.string()
|
||||
.when('enabled', {
|
||||
is: true,
|
||||
then: (password) => password.required('Specify password for proxy authentication.')
|
||||
})
|
||||
.max(1024)
|
||||
})
|
||||
})
|
||||
.optional(),
|
||||
bypassProxy: Yup.string().optional().max(1024)
|
||||
disabled: Yup.boolean().optional(),
|
||||
inherit: Yup.boolean().required(),
|
||||
config: Yup.object({
|
||||
protocol: Yup.string().required().oneOf(['http', 'https', 'socks4', 'socks5']),
|
||||
hostname: Yup.string().max(1024),
|
||||
port: Yup.number()
|
||||
.min(1)
|
||||
.max(65535)
|
||||
.typeError('Specify port between 1 and 65535')
|
||||
.nullable()
|
||||
.transform((_, val) => (val ? Number(val) : null)),
|
||||
auth: Yup.object({
|
||||
disabled: Yup.boolean().optional(),
|
||||
username: Yup.string().max(1024),
|
||||
password: Yup.string().max(1024)
|
||||
}).optional(),
|
||||
bypassProxy: Yup.string().optional().max(1024)
|
||||
}).required()
|
||||
});
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
mode: preferences.proxy.mode,
|
||||
protocol: preferences.proxy.protocol || 'http',
|
||||
hostname: preferences.proxy.hostname || '',
|
||||
port: preferences.proxy.port || 0,
|
||||
auth: {
|
||||
enabled: preferences.proxy.auth ? preferences.proxy.auth.enabled || false : false,
|
||||
username: preferences.proxy.auth ? preferences.proxy.auth.username || '' : '',
|
||||
password: preferences.proxy.auth ? preferences.proxy.auth.password || '' : ''
|
||||
},
|
||||
bypassProxy: preferences.proxy.bypassProxy || ''
|
||||
disabled: preferences.proxy.disabled || false,
|
||||
inherit: preferences.proxy.inherit || false,
|
||||
config: {
|
||||
protocol: preferences.proxy.config?.protocol || 'http',
|
||||
hostname: preferences.proxy.config?.hostname || '',
|
||||
port: preferences.proxy.config?.port || 0,
|
||||
auth: {
|
||||
disabled: preferences.proxy.config?.auth?.disabled || false,
|
||||
username: preferences.proxy.config?.auth?.username || '',
|
||||
password: preferences.proxy.config?.auth?.password || ''
|
||||
},
|
||||
bypassProxy: preferences.proxy.config?.bypassProxy || ''
|
||||
}
|
||||
},
|
||||
validationSchema: proxySchema,
|
||||
onSubmit: (values) => {
|
||||
@@ -103,16 +88,19 @@ const ProxySettings = ({ close }) => {
|
||||
|
||||
useEffect(() => {
|
||||
formik.setValues({
|
||||
mode: preferences.proxy.mode,
|
||||
protocol: preferences.proxy.protocol || 'http',
|
||||
hostname: preferences.proxy.hostname || '',
|
||||
port: preferences.proxy.port || '',
|
||||
auth: {
|
||||
enabled: preferences.proxy.auth ? preferences.proxy.auth.enabled || false : false,
|
||||
username: preferences.proxy.auth ? preferences.proxy.auth.username || '' : '',
|
||||
password: preferences.proxy.auth ? preferences.proxy.auth.password || '' : ''
|
||||
},
|
||||
bypassProxy: preferences.proxy.bypassProxy || ''
|
||||
disabled: preferences.proxy.disabled || false,
|
||||
inherit: preferences.proxy.inherit || false,
|
||||
config: {
|
||||
protocol: preferences.proxy.config?.protocol || 'http',
|
||||
hostname: preferences.proxy.config?.hostname || '',
|
||||
port: preferences.proxy.config?.port || '',
|
||||
auth: {
|
||||
disabled: preferences.proxy.config?.auth?.disabled || false,
|
||||
username: preferences.proxy.config?.auth?.username || '',
|
||||
password: preferences.proxy.config?.auth?.password || ''
|
||||
},
|
||||
bypassProxy: preferences.proxy.config?.bypassProxy || ''
|
||||
}
|
||||
});
|
||||
}, [preferences]);
|
||||
|
||||
@@ -137,10 +125,11 @@ const ProxySettings = ({ close }) => {
|
||||
<input
|
||||
type="radio"
|
||||
name="mode"
|
||||
value="false"
|
||||
checked={formik.values.mode === 'off'}
|
||||
value="off"
|
||||
checked={formik.values.disabled === true}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue('mode', 'off');
|
||||
formik.setFieldValue('disabled', true);
|
||||
formik.setFieldValue('inherit', false);
|
||||
}}
|
||||
className="mr-1 cursor-pointer"
|
||||
/>
|
||||
@@ -150,10 +139,11 @@ const ProxySettings = ({ close }) => {
|
||||
<input
|
||||
type="radio"
|
||||
name="mode"
|
||||
value="true"
|
||||
checked={formik.values.mode === 'on'}
|
||||
value="on"
|
||||
checked={formik.values.disabled === false && formik.values.inherit === false}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue('mode', 'on');
|
||||
formik.setFieldValue('disabled', false);
|
||||
formik.setFieldValue('inherit', false);
|
||||
}}
|
||||
className="mr-1 cursor-pointer"
|
||||
/>
|
||||
@@ -164,15 +154,18 @@ const ProxySettings = ({ close }) => {
|
||||
type="radio"
|
||||
name="mode"
|
||||
value="system"
|
||||
checked={formik.values.mode === 'system'}
|
||||
onChange={formik.handleChange}
|
||||
checked={formik.values.disabled === false && formik.values.inherit === true}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue('disabled', false);
|
||||
formik.setFieldValue('inherit', true);
|
||||
}}
|
||||
className="mr-1 cursor-pointer"
|
||||
/>
|
||||
System Proxy
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{formik?.values?.mode === 'system' ? (
|
||||
{formik.values.disabled === false && formik.values.inherit === true ? (
|
||||
<div className="mb-3 pt-1 text-muted system-proxy-settings">
|
||||
<small>
|
||||
Below values are sourced from your system environment variables and cannot be directly updated in Bruno.<br />
|
||||
@@ -200,7 +193,7 @@ const ProxySettings = ({ close }) => {
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{formik?.values?.mode === 'on' ? (
|
||||
{formik.values.disabled === false && formik.values.inherit === false ? (
|
||||
<>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="protocol">
|
||||
@@ -210,9 +203,9 @@ const ProxySettings = ({ close }) => {
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
name="config.protocol"
|
||||
value="http"
|
||||
checked={formik.values.protocol === 'http'}
|
||||
checked={formik.values.config.protocol === 'http'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
@@ -221,9 +214,9 @@ const ProxySettings = ({ close }) => {
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
name="config.protocol"
|
||||
value="https"
|
||||
checked={formik.values.protocol === 'https'}
|
||||
checked={formik.values.config.protocol === 'https'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
@@ -232,9 +225,9 @@ const ProxySettings = ({ close }) => {
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
name="config.protocol"
|
||||
value="socks4"
|
||||
checked={formik.values.protocol === 'socks4'}
|
||||
checked={formik.values.config.protocol === 'socks4'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
@@ -243,9 +236,9 @@ const ProxySettings = ({ close }) => {
|
||||
<label className="flex items-center ml-4">
|
||||
<input
|
||||
type="radio"
|
||||
name="protocol"
|
||||
name="config.protocol"
|
||||
value="socks5"
|
||||
checked={formik.values.protocol === 'socks5'}
|
||||
checked={formik.values.config.protocol === 'socks5'}
|
||||
onChange={formik.handleChange}
|
||||
className="mr-1"
|
||||
/>
|
||||
@@ -254,92 +247,94 @@ const ProxySettings = ({ close }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="hostname">
|
||||
<label className="settings-label" htmlFor="config.hostname">
|
||||
Hostname
|
||||
</label>
|
||||
<input
|
||||
id="hostname"
|
||||
id="config.hostname"
|
||||
type="text"
|
||||
name="hostname"
|
||||
name="config.hostname"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.hostname || ''}
|
||||
value={formik.values.config.hostname || ''}
|
||||
/>
|
||||
{formik.touched.hostname && formik.errors.hostname ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.hostname}</div>
|
||||
{formik.touched.config?.hostname && formik.errors.config?.hostname ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.config.hostname}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="port">
|
||||
<label className="settings-label" htmlFor="config.port">
|
||||
Port
|
||||
</label>
|
||||
<input
|
||||
id="port"
|
||||
id="config.port"
|
||||
type="number"
|
||||
name="port"
|
||||
name="config.port"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.port}
|
||||
value={formik.values.config.port}
|
||||
/>
|
||||
{formik.touched.port && formik.errors.port ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.port}</div>
|
||||
{formik.touched.config?.port && formik.errors.config?.port ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.config.port}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.enabled">
|
||||
<label className="settings-label" htmlFor="config.auth.disabled">
|
||||
Auth
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
name="auth.enabled"
|
||||
checked={formik.values.auth.enabled}
|
||||
onChange={formik.handleChange}
|
||||
name="config.auth.disabled"
|
||||
checked={!formik.values.config.auth.disabled}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue('config.auth.disabled', !e.target.checked);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.username">
|
||||
<label className="settings-label" htmlFor="config.auth.username">
|
||||
Username
|
||||
</label>
|
||||
<input
|
||||
id="auth.username"
|
||||
id="config.auth.username"
|
||||
type="text"
|
||||
name="auth.username"
|
||||
name="config.auth.username"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.username}
|
||||
value={formik.values.config.auth.username}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
{formik.touched.auth?.username && formik.errors.auth?.username ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.auth.username}</div>
|
||||
{formik.touched.config?.auth?.username && formik.errors.config?.auth?.username ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.config.auth.username}</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="auth.password">
|
||||
<label className="settings-label" htmlFor="config.auth.password">
|
||||
Password
|
||||
</label>
|
||||
<div className="textbox flex flex-row items-center w-[13.2rem] h-[2.25rem] relative">
|
||||
<input
|
||||
id="auth.password"
|
||||
id="config.auth.password"
|
||||
type={passwordVisible ? `text` : 'password'}
|
||||
name="auth.password"
|
||||
name="config.auth.password"
|
||||
className="outline-none w-[10.5rem] bg-transparent"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.password}
|
||||
value={formik.values.config.auth.password}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<button
|
||||
@@ -350,29 +345,29 @@ const ProxySettings = ({ close }) => {
|
||||
{passwordVisible ? <IconEyeOff size={18} strokeWidth={2} /> : <IconEye size={18} strokeWidth={2} />}
|
||||
</button>
|
||||
</div>
|
||||
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
|
||||
{formik.touched.config?.auth?.password && formik.errors.config?.auth?.password ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.config.auth.password}</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="bypassProxy">
|
||||
<label className="settings-label" htmlFor="config.bypassProxy">
|
||||
Proxy Bypass
|
||||
</label>
|
||||
<input
|
||||
id="bypassProxy"
|
||||
id="config.bypassProxy"
|
||||
type="text"
|
||||
name="bypassProxy"
|
||||
name="config.bypassProxy"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.bypassProxy || ''}
|
||||
value={formik.values.config.bypassProxy || ''}
|
||||
/>
|
||||
{formik.touched.bypassProxy && formik.errors.bypassProxy ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.bypassProxy}</div>
|
||||
{formik.touched.config?.bypassProxy && formik.errors.config?.bypassProxy ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.config.bypassProxy}</div>
|
||||
) : null}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/preset-env": "^7.25.4",
|
||||
"@opencollection/types": "0.3.0",
|
||||
"@usebruno/schema-types": "0.0.1",
|
||||
"@opencollection/types": "~0.5.0",
|
||||
"@rollup/plugin-alias": "^5.1.0",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-typescript": "^9.0.2",
|
||||
"@usebruno/schema-types": "0.0.1",
|
||||
"@web/rollup-plugin-copy": "^0.5.1",
|
||||
"babel-jest": "^29.7.0",
|
||||
"rimraf": "^5.0.7",
|
||||
|
||||
@@ -32,27 +32,12 @@ const toOpenCollectionConfig = (brunoConfig: BrunoConfig | undefined): Collectio
|
||||
}
|
||||
}
|
||||
|
||||
if (brunoConfig.proxy?.enabled) {
|
||||
if (brunoConfig.proxy.enabled === 'global') {
|
||||
config.proxy = 'inherit';
|
||||
} else {
|
||||
config.proxy = {
|
||||
protocol: brunoConfig.proxy.protocol || 'http',
|
||||
hostname: brunoConfig.proxy.hostname || '',
|
||||
port: brunoConfig.proxy.port || 0
|
||||
};
|
||||
|
||||
if (brunoConfig.proxy.auth?.enabled) {
|
||||
config.proxy.auth = {
|
||||
username: brunoConfig.proxy.auth.username || '',
|
||||
password: brunoConfig.proxy.auth.password || ''
|
||||
};
|
||||
}
|
||||
|
||||
if (brunoConfig.proxy.bypassProxy) {
|
||||
config.proxy.bypassProxy = brunoConfig.proxy.bypassProxy;
|
||||
}
|
||||
}
|
||||
if (brunoConfig.proxy) {
|
||||
config.proxy = {
|
||||
disabled: brunoConfig.proxy.disabled,
|
||||
inherit: brunoConfig.proxy.inherit,
|
||||
config: brunoConfig.proxy.config
|
||||
};
|
||||
}
|
||||
|
||||
if (brunoConfig.clientCertificates?.certs?.length) {
|
||||
|
||||
@@ -124,7 +124,7 @@ const fromOpenCollectionOAuth2 = (auth: AuthOAuth2): BrunoAuth => {
|
||||
clientId: auth.credentials?.clientId || null,
|
||||
clientSecret: auth.credentials?.clientSecret || null,
|
||||
scope: auth.scope || null,
|
||||
pkce: auth.pkce?.enabled || null,
|
||||
pkce: (auth.pkce && !auth.pkce.disabled) || null,
|
||||
credentialsPlacement: getCredentialsPlacement(auth.credentials),
|
||||
credentialsId: auth.tokenConfig?.id || 'credentials',
|
||||
tokenPlacement: getTokenPlacement(auth.tokenConfig),
|
||||
@@ -357,7 +357,7 @@ const toOpenCollectionOAuth2 = (oauth2: BrunoOAuth2 | null | undefined): AuthOAu
|
||||
placement: oauth2.credentialsPlacement === 'basic_auth_header' ? 'basic_auth_header' : 'body'
|
||||
},
|
||||
scope: oauth2.scope || '',
|
||||
pkce: oauth2.pkce ? { enabled: true, method: 'S256' } : undefined,
|
||||
pkce: oauth2.pkce ? { method: 'S256' } : undefined,
|
||||
tokenConfig: {
|
||||
id: oauth2.credentialsId || 'credentials',
|
||||
placement: oauth2.tokenPlacement === 'query'
|
||||
|
||||
@@ -36,30 +36,12 @@ const fromOpenCollectionConfig = (oc: OpenCollection): BrunoConfig => {
|
||||
};
|
||||
}
|
||||
|
||||
if (config.proxy && typeof config.proxy !== 'boolean') {
|
||||
if (config.proxy === 'inherit') {
|
||||
brunoConfig.proxy = { enabled: 'global' };
|
||||
} else {
|
||||
const proxyConfig = config.proxy;
|
||||
brunoConfig.proxy = {
|
||||
enabled: true,
|
||||
protocol: proxyConfig.protocol || 'http',
|
||||
hostname: proxyConfig.hostname || '',
|
||||
port: proxyConfig.port || 0
|
||||
};
|
||||
|
||||
if (proxyConfig.auth) {
|
||||
brunoConfig.proxy.auth = {
|
||||
enabled: true,
|
||||
username: proxyConfig.auth.username || '',
|
||||
password: proxyConfig.auth.password || ''
|
||||
};
|
||||
}
|
||||
|
||||
if (proxyConfig.bypassProxy) {
|
||||
brunoConfig.proxy.bypassProxy = proxyConfig.bypassProxy;
|
||||
}
|
||||
}
|
||||
if (config.proxy) {
|
||||
brunoConfig.proxy = {
|
||||
disabled: config.proxy.disabled,
|
||||
inherit: config.proxy.inherit,
|
||||
config: config.proxy.config
|
||||
};
|
||||
}
|
||||
|
||||
if (config.clientCertificates?.length) {
|
||||
|
||||
@@ -66,9 +66,10 @@ export type {
|
||||
} from '@opencollection/types/requests/websocket';
|
||||
|
||||
// OpenCollection config types
|
||||
export type { Environment, CollectionConfig } from '@opencollection/types/config/environments';
|
||||
export type { Environment } from '@opencollection/types/config/environments';
|
||||
export type { CollectionConfig } from '@opencollection/types/config/collection';
|
||||
export type { Protobuf, ProtoFileItem, ProtoFileImportPath } from '@opencollection/types/config/protobuf';
|
||||
export type { Proxy, ProxyAuth } from '@opencollection/types/config/proxy';
|
||||
export type { Proxy, ProxyConnectionConfig, ProxyConnectionAuth } from '@opencollection/types/config/proxy';
|
||||
export type { ClientCertificate, PemCertificate, Pkcs12Certificate } from '@opencollection/types/config/certificates';
|
||||
|
||||
// OpenCollection common types
|
||||
@@ -175,16 +176,19 @@ export interface BrunoConfig {
|
||||
importPaths?: { path: string; disabled?: boolean }[];
|
||||
};
|
||||
proxy?: {
|
||||
enabled?: boolean | 'global';
|
||||
protocol?: string;
|
||||
hostname?: string;
|
||||
port?: number;
|
||||
auth?: {
|
||||
enabled?: boolean;
|
||||
username?: string;
|
||||
password?: string;
|
||||
disabled?: boolean;
|
||||
inherit?: boolean;
|
||||
config?: {
|
||||
protocol?: string;
|
||||
hostname?: string;
|
||||
port?: number;
|
||||
auth?: {
|
||||
disabled?: boolean;
|
||||
username?: string;
|
||||
password?: string;
|
||||
};
|
||||
bypassProxy?: string;
|
||||
};
|
||||
bypassProxy?: string;
|
||||
};
|
||||
clientCertificates?: {
|
||||
certs?: Array<{
|
||||
|
||||
@@ -27,7 +27,7 @@ const EnvironmentSecretsStore = require('../store/env-secrets');
|
||||
const UiStateSnapshot = require('../store/ui-state-snapshot');
|
||||
const { parseFileMeta, hydrateRequestWithUuid } = require('../utils/collection');
|
||||
const { parseLargeRequestWithRedaction } = require('../utils/parse');
|
||||
const { transformBrunoConfigAfterRead } = require('../utils/transfomBrunoConfig');
|
||||
const { transformBrunoConfigAfterRead } = require('../utils/transformBrunoConfig');
|
||||
|
||||
const MAX_FILE_SIZE = 2.5 * 1024 * 1024;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const { dialog, ipcMain } = require('electron');
|
||||
const Yup = require('yup');
|
||||
const { isDirectory, getCollectionStats, normalizeAndResolvePath } = require('../utils/filesystem');
|
||||
const { generateUidBasedOnHash } = require('../utils/common');
|
||||
const { transformBrunoConfigAfterRead } = require('../utils/transfomBrunoConfig');
|
||||
const { transformBrunoConfigAfterRead } = require('../utils/transformBrunoConfig');
|
||||
const { parseCollection } = require('@usebruno/filestore');
|
||||
|
||||
// todo: bruno.json config schema validation errors must be propagated to the UI
|
||||
|
||||
@@ -62,7 +62,7 @@ const { getProcessEnvVars } = require('../store/process-env');
|
||||
const { getOAuth2TokenUsingAuthorizationCode, getOAuth2TokenUsingClientCredentials, getOAuth2TokenUsingPasswordCredentials, getOAuth2TokenUsingImplicitGrant, refreshOauth2Token } = require('../utils/oauth2');
|
||||
const { getCertsAndProxyConfig } = require('./network/cert-utils');
|
||||
const collectionWatcher = require('../app/collection-watcher');
|
||||
const { transformBrunoConfigBeforeSave } = require('../utils/transfomBrunoConfig');
|
||||
const { transformBrunoConfigBeforeSave } = require('../utils/transformBrunoConfig');
|
||||
const { REQUEST_TYPES } = require('../utils/constants');
|
||||
const { cancelOAuth2AuthorizationRequest, isOauth2AuthorizationRequestInProgress } = require('../utils/oauth2-protocol-handler');
|
||||
|
||||
|
||||
@@ -101,12 +101,14 @@ const getCertsAndProxyConfig = async ({
|
||||
/**
|
||||
* Proxy configuration
|
||||
*
|
||||
* Preferences proxyMode has three possible values: on, off, system
|
||||
* Collection proxyMode has three possible values: true, false, global
|
||||
* New format:
|
||||
* - disabled: boolean (optional, defaults to false)
|
||||
* - inherit: boolean (required)
|
||||
* - config: { protocol, hostname, port, auth, bypassProxy }
|
||||
*
|
||||
* When collection proxyMode is true, it overrides the app-level proxy settings
|
||||
* When collection proxyMode is false, it ignores the app-level proxy settings
|
||||
* When collection proxyMode is global, it uses the app-level proxy settings
|
||||
* When collection proxy has inherit=false and disabled=false, use collection-specific proxy
|
||||
* When collection proxy has inherit=true, inherit from global preferences
|
||||
* When disabled=true, proxy is disabled
|
||||
*
|
||||
* Below logic calculates the proxyMode and proxyConfig to be used for the request
|
||||
*/
|
||||
@@ -114,14 +116,32 @@ const getCertsAndProxyConfig = async ({
|
||||
let proxyConfig = {};
|
||||
|
||||
const collectionProxyConfig = get(brunoConfig, 'proxy', {});
|
||||
const collectionProxyEnabled = get(collectionProxyConfig, 'enabled', 'global');
|
||||
if (collectionProxyEnabled === true) {
|
||||
proxyConfig = collectionProxyConfig;
|
||||
const collectionProxyDisabled = get(collectionProxyConfig, 'disabled', false);
|
||||
const collectionProxyInherit = get(collectionProxyConfig, 'inherit', true);
|
||||
const collectionProxyConfigData = get(collectionProxyConfig, 'config', collectionProxyConfig);
|
||||
|
||||
if (!collectionProxyDisabled && !collectionProxyInherit) {
|
||||
// Use collection-specific proxy
|
||||
proxyConfig = collectionProxyConfigData;
|
||||
proxyMode = 'on';
|
||||
} else if (collectionProxyEnabled === 'global') {
|
||||
proxyConfig = preferencesUtil.getGlobalProxyConfig();
|
||||
proxyMode = get(proxyConfig, 'mode', 'off');
|
||||
} else if (!collectionProxyDisabled && collectionProxyInherit) {
|
||||
// Inherit from global preferences
|
||||
const globalProxy = preferencesUtil.getGlobalProxyConfig();
|
||||
const globalDisabled = get(globalProxy, 'disabled', false);
|
||||
const globalInherit = get(globalProxy, 'inherit', false);
|
||||
const globalProxyConfigData = get(globalProxy, 'config', globalProxy);
|
||||
|
||||
if (!globalDisabled && !globalInherit) {
|
||||
// Use global custom proxy
|
||||
proxyConfig = globalProxyConfigData;
|
||||
proxyMode = 'on';
|
||||
} else if (!globalDisabled && globalInherit) {
|
||||
// Use system proxy
|
||||
proxyMode = 'system';
|
||||
}
|
||||
// else: global proxy is disabled, proxyMode stays 'off'
|
||||
}
|
||||
// else: collection proxy is disabled, proxyMode stays 'off'
|
||||
|
||||
return { proxyMode, proxyConfig, httpsAgentRequestFields, interpolationOptions };
|
||||
};
|
||||
|
||||
@@ -30,16 +30,17 @@ const defaultPreferences = {
|
||||
codeFontSize: 13
|
||||
},
|
||||
proxy: {
|
||||
mode: 'off',
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
responsePaneOrientation: 'horizontal'
|
||||
@@ -79,16 +80,19 @@ const preferencesSchema = Yup.object().shape({
|
||||
codeFontSize: Yup.number().min(1).max(32).nullable()
|
||||
}),
|
||||
proxy: Yup.object({
|
||||
mode: Yup.string().oneOf(['off', 'on', 'system']),
|
||||
protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']),
|
||||
hostname: Yup.string().max(1024),
|
||||
port: Yup.number().min(1).max(65535).nullable(),
|
||||
auth: Yup.object({
|
||||
enabled: Yup.boolean(),
|
||||
username: Yup.string().max(1024),
|
||||
password: Yup.string().max(1024)
|
||||
}).optional(),
|
||||
bypassProxy: Yup.string().optional().max(1024)
|
||||
disabled: Yup.boolean().optional(),
|
||||
inherit: Yup.boolean().required(),
|
||||
config: Yup.object({
|
||||
protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']),
|
||||
hostname: Yup.string().max(1024),
|
||||
port: Yup.number().min(1).max(65535).nullable(),
|
||||
auth: Yup.object({
|
||||
disabled: Yup.boolean().optional(),
|
||||
username: Yup.string().max(1024),
|
||||
password: Yup.string().max(1024)
|
||||
}).optional(),
|
||||
bypassProxy: Yup.string().optional().max(1024)
|
||||
}).required()
|
||||
}),
|
||||
layout: Yup.object({
|
||||
responsePaneOrientation: Yup.string().oneOf(['horizontal', 'vertical'])
|
||||
@@ -118,17 +122,73 @@ class PreferencesStore {
|
||||
getPreferences() {
|
||||
let preferences = this.store.get('preferences', {});
|
||||
|
||||
// This to support the old preferences format
|
||||
// In the old format, we had a proxy.enabled flag
|
||||
// In the new format, this maps to proxy.mode = 'on'
|
||||
if (preferences?.proxy?.enabled) {
|
||||
preferences.proxy.mode = 'on';
|
||||
}
|
||||
// Migrate proxy configuration from old formats to new format
|
||||
const proxyMigrated = get(preferences, '_migrations.proxyConfigFormat', false);
|
||||
if (!proxyMigrated && preferences?.proxy) {
|
||||
const proxy = preferences.proxy;
|
||||
|
||||
// Delete the proxy.enabled property if it exists, regardless of its value
|
||||
// This is a part of migration to the new preferences format
|
||||
if (preferences?.proxy && 'enabled' in preferences.proxy) {
|
||||
delete preferences.proxy.enabled;
|
||||
// Check if this is an old format that needs migration
|
||||
const hasOldFormat = 'enabled' in proxy || 'mode' in proxy;
|
||||
|
||||
if (hasOldFormat) {
|
||||
let newProxy = {
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: proxy.protocol || 'http',
|
||||
hostname: proxy.hostname || '',
|
||||
port: proxy.port || null,
|
||||
auth: {
|
||||
username: get(proxy, 'auth.username', ''),
|
||||
password: get(proxy, 'auth.password', '')
|
||||
},
|
||||
bypassProxy: proxy.bypassProxy || ''
|
||||
}
|
||||
};
|
||||
|
||||
// Handle old format 1: enabled (boolean)
|
||||
if ('enabled' in proxy && typeof proxy.enabled === 'boolean') {
|
||||
newProxy.disabled = !proxy.enabled;
|
||||
newProxy.inherit = false;
|
||||
} else if ('mode' in proxy) {
|
||||
// Handle old format 2: mode ('off' | 'on' | 'system')
|
||||
if (proxy.mode === 'off') {
|
||||
newProxy.disabled = true;
|
||||
newProxy.inherit = false;
|
||||
} else if (proxy.mode === 'on') {
|
||||
newProxy.disabled = false;
|
||||
newProxy.inherit = false;
|
||||
} else if (proxy.mode === 'system') {
|
||||
newProxy.disabled = false;
|
||||
newProxy.inherit = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate auth.enabled to auth.disabled
|
||||
if (get(proxy, 'auth.enabled') === false) {
|
||||
newProxy.config.auth.disabled = true;
|
||||
}
|
||||
// If auth.enabled is true or undefined, omit disabled (defaults to false)
|
||||
|
||||
// Omit disabled: false at top level (optional field)
|
||||
if (newProxy.disabled === false) {
|
||||
delete newProxy.disabled;
|
||||
}
|
||||
// Omit auth.disabled: false (optional field)
|
||||
if (newProxy.config.auth.disabled === false) {
|
||||
delete newProxy.config.auth.disabled;
|
||||
}
|
||||
|
||||
preferences.proxy = newProxy;
|
||||
|
||||
// Mark migration as complete // ?
|
||||
// if (!preferences._migrations) {
|
||||
// preferences._migrations = {};
|
||||
// }
|
||||
// preferences._migrations.proxyConfigFormat = true;
|
||||
|
||||
// Save the migrated preferences back to the store
|
||||
// this.store.set('preferences', preferences);
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate font size from 14px to 13px for existing users
|
||||
|
||||
@@ -318,7 +318,8 @@ function setupProxyAgents({
|
||||
const proxyProtocol = interpolateString(get(proxyConfig, 'protocol'), interpolationOptions);
|
||||
const proxyHostname = interpolateString(get(proxyConfig, 'hostname'), interpolationOptions);
|
||||
const proxyPort = interpolateString(get(proxyConfig, 'port'), interpolationOptions);
|
||||
const proxyAuthEnabled = get(proxyConfig, 'auth.enabled', false);
|
||||
const proxyAuthDisabled = get(proxyConfig, 'auth.disabled', false);
|
||||
const proxyAuthEnabled = !proxyAuthDisabled;
|
||||
const socksEnabled = proxyProtocol.includes('socks');
|
||||
|
||||
let uriPort = isUndefined(proxyPort) || isNull(proxyPort) ? '' : `:${proxyPort}`;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const path = require('path');
|
||||
const { isFile, isDirectory } = require('./filesystem');
|
||||
const { get } = require('lodash');
|
||||
|
||||
function transformBrunoConfigBeforeSave(brunoConfig) {
|
||||
// remove exists from importPaths and protoFiles
|
||||
@@ -16,6 +17,18 @@ function transformBrunoConfigBeforeSave(brunoConfig) {
|
||||
});
|
||||
}
|
||||
|
||||
// Clean up proxy config before saving
|
||||
if (brunoConfig.proxy) {
|
||||
// Remove disabled: false (optional field)
|
||||
if (brunoConfig.proxy.disabled === false) {
|
||||
delete brunoConfig.proxy.disabled;
|
||||
}
|
||||
// Remove auth.disabled: false (optional field)
|
||||
if (brunoConfig.proxy.config?.auth?.disabled === false) {
|
||||
delete brunoConfig.proxy.config.auth.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
return brunoConfig;
|
||||
}
|
||||
|
||||
@@ -61,6 +74,59 @@ async function transformBrunoConfigAfterRead(brunoConfig, collectionPathname) {
|
||||
}));
|
||||
}
|
||||
|
||||
// Migrate proxy configuration from old format to new format
|
||||
if (brunoConfig.proxy) {
|
||||
const proxy = brunoConfig.proxy;
|
||||
|
||||
// Check if this is an old format (has 'enabled' property)
|
||||
if ('enabled' in proxy) {
|
||||
const enabled = proxy.enabled;
|
||||
|
||||
let newProxy = {
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: proxy.protocol || 'http',
|
||||
hostname: proxy.hostname || '',
|
||||
port: proxy.port || null,
|
||||
auth: {
|
||||
username: get(proxy, 'auth.username', ''),
|
||||
password: get(proxy, 'auth.password', '')
|
||||
},
|
||||
bypassProxy: proxy.bypassProxy || ''
|
||||
}
|
||||
};
|
||||
|
||||
// Handle old format: enabled (true | false | 'global')
|
||||
if (enabled === true) {
|
||||
newProxy.disabled = false;
|
||||
newProxy.inherit = false;
|
||||
} else if (enabled === false) {
|
||||
newProxy.disabled = true;
|
||||
newProxy.inherit = false;
|
||||
} else if (enabled === 'global') {
|
||||
newProxy.disabled = false;
|
||||
newProxy.inherit = true;
|
||||
}
|
||||
|
||||
// Migrate auth.enabled to auth.disabled
|
||||
if (get(proxy, 'auth.enabled') === false) {
|
||||
newProxy.config.auth.disabled = true;
|
||||
}
|
||||
// If auth.enabled is true or undefined, omit disabled (defaults to false)
|
||||
|
||||
// Omit disabled: false at top level (optional field)
|
||||
if (newProxy.disabled === false) {
|
||||
delete newProxy.disabled;
|
||||
}
|
||||
// Omit auth.disabled: false (optional field)
|
||||
if (newProxy.config.auth.disabled === false) {
|
||||
delete newProxy.config.auth.disabled;
|
||||
}
|
||||
|
||||
brunoConfig.proxy = newProxy;
|
||||
}
|
||||
}
|
||||
|
||||
return brunoConfig;
|
||||
}
|
||||
|
||||
297
packages/bruno-electron/tests/store/proxy-preferences.spec.js
Normal file
297
packages/bruno-electron/tests/store/proxy-preferences.spec.js
Normal file
@@ -0,0 +1,297 @@
|
||||
let mockStoreData = {};
|
||||
|
||||
jest.mock('electron-store', () => {
|
||||
return jest.fn().mockImplementation((opts = {}) => {
|
||||
return {
|
||||
get: (key, fallback) => (key in mockStoreData ? mockStoreData[key] : fallback),
|
||||
set: (key, value) => {
|
||||
mockStoreData[key] = value;
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const { getPreferences, savePreferences } = require('../../src/store/preferences');
|
||||
|
||||
describe('Proxy Preferences Migration', () => {
|
||||
beforeEach(() => {
|
||||
// Reset mock store data before each test
|
||||
mockStoreData = {};
|
||||
});
|
||||
|
||||
describe('New Format (no migration needed)', () => {
|
||||
it('should handle new format with inherit: false', () => {
|
||||
const newFormatProxy = {
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: 'localhost'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = newFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// Verify key fields are preserved from stored preferences
|
||||
expect(preferences.proxy.inherit).toBe(false);
|
||||
expect(preferences.proxy.config.protocol).toBe('http');
|
||||
expect(preferences.proxy.config.hostname).toBe('proxy.example.com');
|
||||
expect(preferences.proxy.config.port).toBe(8080);
|
||||
expect(preferences.proxy.config.auth.username).toBe('user');
|
||||
expect(preferences.proxy.config.auth.password).toBe('pass');
|
||||
expect(preferences.proxy.config.bypassProxy).toBe('localhost');
|
||||
});
|
||||
|
||||
it('should handle new format with inherit: true', () => {
|
||||
const newFormatProxy = {
|
||||
proxy: {
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = newFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
expect(preferences.proxy.inherit).toBe(true);
|
||||
expect(preferences.proxy.config).toBeDefined();
|
||||
});
|
||||
|
||||
it('should handle new format with disabled: true', () => {
|
||||
const newFormatProxy = {
|
||||
proxy: {
|
||||
disabled: true,
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = newFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// disabled: true is preserved from stored preferences
|
||||
expect(preferences.proxy.disabled).toBe(true);
|
||||
expect(preferences.proxy.inherit).toBe(false);
|
||||
expect(preferences.proxy.config).toBeDefined();
|
||||
});
|
||||
|
||||
it('should handle new format with auth.disabled: true', () => {
|
||||
const newFormatProxy = {
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
disabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = newFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// auth.disabled: true is preserved from stored preferences
|
||||
expect(preferences.proxy.config.auth.disabled).toBe(true);
|
||||
expect(preferences.proxy.config.auth.username).toBe('user');
|
||||
expect(preferences.proxy.config.auth.password).toBe('pass');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Old Format 1: enabled (boolean)', () => {
|
||||
it('should migrate enabled: true to disabled: false, inherit: false', () => {
|
||||
const oldFormatProxy = {
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: 'localhost'
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = oldFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// After migration, inherit should be false (old enabled: true maps to inherit: false)
|
||||
expect(preferences.proxy.inherit).toBe(false);
|
||||
// Values are preserved from stored preferences
|
||||
expect(preferences.proxy.config.protocol).toBe('http');
|
||||
expect(preferences.proxy.config.hostname).toBe('proxy.example.com');
|
||||
expect(preferences.proxy.config.port).toBe(8080);
|
||||
expect(preferences.proxy.config.auth.username).toBe('user');
|
||||
expect(preferences.proxy.config.auth.password).toBe('pass');
|
||||
expect(preferences.proxy.config.bypassProxy).toBe('localhost');
|
||||
expect(preferences.proxy.disabled).toBeUndefined(); // disabled: false is omitted
|
||||
});
|
||||
|
||||
it('should migrate enabled: false to disabled: true, inherit: false', () => {
|
||||
const oldFormatProxy = {
|
||||
proxy: {
|
||||
enabled: false,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = oldFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// After migration, enabled: false becomes disabled: true, inherit: false
|
||||
expect(preferences.proxy.disabled).toBe(true);
|
||||
expect(preferences.proxy.inherit).toBe(false);
|
||||
});
|
||||
|
||||
it('should migrate auth.enabled: false to auth.disabled: true', () => {
|
||||
const oldFormatProxy = {
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = oldFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// auth.disabled: true is preserved from stored preferences
|
||||
expect(preferences.proxy.config.auth.disabled).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Old Format 2: mode (string)', () => {
|
||||
it('should migrate mode: "off" to disabled: true, inherit: false', () => {
|
||||
const oldFormatProxy = {
|
||||
proxy: {
|
||||
mode: 'off',
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = oldFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
// disabled: true is preserved from migration
|
||||
expect(preferences.proxy.disabled).toBe(true);
|
||||
expect(preferences.proxy.inherit).toBe(false);
|
||||
});
|
||||
|
||||
it('should migrate mode: "on" to disabled: false, inherit: false', () => {
|
||||
const oldFormatProxy = {
|
||||
proxy: {
|
||||
mode: 'on',
|
||||
protocol: 'https',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8443,
|
||||
auth: {
|
||||
enabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: '*.local'
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = oldFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
expect(preferences.proxy.disabled).toBeUndefined(); // disabled: false is omitted
|
||||
expect(preferences.proxy.inherit).toBe(false);
|
||||
// Values are preserved from stored preferences
|
||||
expect(preferences.proxy.config.protocol).toBe('https');
|
||||
expect(preferences.proxy.config.hostname).toBe('proxy.example.com');
|
||||
expect(preferences.proxy.config.port).toBe(8443);
|
||||
});
|
||||
|
||||
it('should migrate mode: "system" to disabled: false, inherit: true', () => {
|
||||
const oldFormatProxy = {
|
||||
proxy: {
|
||||
mode: 'system',
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
mockStoreData['preferences'] = oldFormatProxy;
|
||||
|
||||
const preferences = getPreferences();
|
||||
|
||||
expect(preferences.proxy.disabled).toBeUndefined(); // disabled: false is omitted
|
||||
expect(preferences.proxy.inherit).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,570 @@
|
||||
const { transformBrunoConfigBeforeSave, transformBrunoConfigAfterRead } = require('../../src/utils/transformBrunoConfig');
|
||||
|
||||
describe('BrunoConfig Proxy Transform', () => {
|
||||
describe('transformBrunoConfigAfterRead - Migration from old to new format', () => {
|
||||
describe('Old Format: enabled (true | false | "global")', () => {
|
||||
test('should migrate enabled: true to disabled: false, inherit: false', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: 'localhost'
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy).toEqual({
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: 'localhost'
|
||||
}
|
||||
});
|
||||
expect(result.proxy.disabled).toBeUndefined(); // disabled: false is omitted
|
||||
});
|
||||
|
||||
test('should migrate enabled: false to disabled: true, inherit: false', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: false,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.disabled).toBe(true);
|
||||
expect(result.proxy.inherit).toBe(false);
|
||||
});
|
||||
|
||||
test('should migrate enabled: "global" to disabled: false, inherit: true', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: 'global',
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.disabled).toBeUndefined(); // disabled: false is omitted
|
||||
expect(result.proxy.inherit).toBe(true);
|
||||
});
|
||||
|
||||
test('should migrate auth.enabled: false to auth.disabled: true', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.config.auth.disabled).toBe(true);
|
||||
expect(result.proxy.config.auth.username).toBe('user');
|
||||
expect(result.proxy.config.auth.password).toBe('pass');
|
||||
});
|
||||
|
||||
test('should omit auth.disabled when auth.enabled: true', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.config.auth.disabled).toBeUndefined();
|
||||
expect(result.proxy.config.auth.username).toBe('user');
|
||||
expect(result.proxy.config.auth.password).toBe('pass');
|
||||
});
|
||||
});
|
||||
|
||||
describe('New Format (no migration)', () => {
|
||||
test('should not modify new format with inherit: false', async () => {
|
||||
const newConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'https',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8443,
|
||||
auth: {
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: '*.local'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(newConfig, '/test/path');
|
||||
|
||||
expect(result.proxy).toEqual(newConfig.proxy);
|
||||
});
|
||||
|
||||
test('should not modify new format with inherit: true', async () => {
|
||||
const newConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(newConfig, '/test/path');
|
||||
|
||||
expect(result.proxy).toEqual(newConfig.proxy);
|
||||
});
|
||||
|
||||
test('should not modify new format with disabled: true', async () => {
|
||||
const newConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
disabled: true,
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(newConfig, '/test/path');
|
||||
|
||||
expect(result.proxy).toEqual(newConfig.proxy);
|
||||
});
|
||||
|
||||
test('should not modify new format with auth.disabled: true', async () => {
|
||||
const newConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
disabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(newConfig, '/test/path');
|
||||
|
||||
expect(result.proxy).toEqual(newConfig.proxy);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
test('should handle missing proxy config', async () => {
|
||||
const config = {
|
||||
name: 'Test Collection'
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(config, '/test/path');
|
||||
|
||||
expect(result.proxy).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should handle null port values', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: null,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.config.port).toBeNull();
|
||||
});
|
||||
|
||||
test('should handle SOCKS protocols', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'socks5',
|
||||
hostname: 'socks.example.com',
|
||||
port: 1080,
|
||||
auth: {
|
||||
enabled: true,
|
||||
username: 'socksuser',
|
||||
password: 'sockspass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.config.protocol).toBe('socks5');
|
||||
expect(result.proxy.config.hostname).toBe('socks.example.com');
|
||||
expect(result.proxy.config.port).toBe(1080);
|
||||
});
|
||||
|
||||
test('should handle missing auth object', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.proxy.config.auth).toEqual({
|
||||
username: '',
|
||||
password: ''
|
||||
});
|
||||
});
|
||||
|
||||
test('should preserve protobuf config during proxy migration', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
protobuf: {
|
||||
protoFiles: [{ path: 'test.proto' }],
|
||||
importPaths: [{ path: 'imports/' }]
|
||||
},
|
||||
proxy: {
|
||||
enabled: 'global',
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
const result = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
expect(result.protobuf).toBeDefined();
|
||||
expect(result.protobuf.protoFiles).toHaveLength(1);
|
||||
expect(result.proxy.inherit).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformBrunoConfigBeforeSave - Cleanup optional fields', () => {
|
||||
test('should remove disabled: false from proxy config', () => {
|
||||
const config = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
disabled: false,
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
expect(result.proxy.disabled).toBeUndefined();
|
||||
expect(result.proxy.inherit).toBe(false);
|
||||
});
|
||||
|
||||
test('should keep disabled: true in proxy config', () => {
|
||||
const config = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
disabled: true,
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
expect(result.proxy.disabled).toBe(true);
|
||||
});
|
||||
|
||||
test('should remove auth.disabled: false from proxy config', () => {
|
||||
const config = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
disabled: false,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
expect(result.proxy.config.auth.disabled).toBeUndefined();
|
||||
expect(result.proxy.config.auth.username).toBe('user');
|
||||
});
|
||||
|
||||
test('should keep auth.disabled: true in proxy config', () => {
|
||||
const config = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
disabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
expect(result.proxy.config.auth.disabled).toBe(true);
|
||||
});
|
||||
|
||||
test('should handle missing proxy config', () => {
|
||||
const config = {
|
||||
name: 'Test Collection'
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
expect(result.proxy).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should preserve protobuf config cleanup', () => {
|
||||
const config = {
|
||||
name: 'Test Collection',
|
||||
protobuf: {
|
||||
protoFiles: [{ path: 'test.proto', exists: true }],
|
||||
importPaths: [{ path: 'imports/', exists: false }]
|
||||
},
|
||||
proxy: {
|
||||
disabled: false,
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
disabled: false,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
// Protobuf exists fields should be removed
|
||||
expect(result.protobuf.protoFiles[0].exists).toBeUndefined();
|
||||
expect(result.protobuf.importPaths[0].exists).toBeUndefined();
|
||||
|
||||
// Proxy optional fields should be removed
|
||||
expect(result.proxy.disabled).toBeUndefined();
|
||||
expect(result.proxy.config.auth.disabled).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should not modify config without optional fields', () => {
|
||||
const config = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: null,
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const result = transformBrunoConfigBeforeSave(config);
|
||||
|
||||
expect(result.proxy).toEqual(config.proxy);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Round-trip transformation', () => {
|
||||
test('should handle read -> save -> read cycle for old format', async () => {
|
||||
const oldConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
enabled: true,
|
||||
protocol: 'http',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8080,
|
||||
auth: {
|
||||
enabled: true,
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: 'localhost'
|
||||
}
|
||||
};
|
||||
|
||||
// Read (migrate)
|
||||
const afterRead = await transformBrunoConfigAfterRead(oldConfig, '/test/path');
|
||||
|
||||
// Save (cleanup)
|
||||
const beforeSave = transformBrunoConfigBeforeSave(afterRead);
|
||||
|
||||
// Read again (should not change)
|
||||
const afterSecondRead = await transformBrunoConfigAfterRead(beforeSave, '/test/path');
|
||||
|
||||
expect(afterSecondRead.proxy).toEqual(beforeSave.proxy);
|
||||
expect(afterSecondRead.proxy.inherit).toBe(false);
|
||||
expect(afterSecondRead.proxy.disabled).toBeUndefined();
|
||||
expect(afterSecondRead.proxy.config.auth.disabled).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should handle read -> save -> read cycle for new format', async () => {
|
||||
const newConfig = {
|
||||
name: 'Test Collection',
|
||||
proxy: {
|
||||
inherit: false,
|
||||
config: {
|
||||
protocol: 'https',
|
||||
hostname: 'proxy.example.com',
|
||||
port: 8443,
|
||||
auth: {
|
||||
username: 'user',
|
||||
password: 'pass'
|
||||
},
|
||||
bypassProxy: '*.local'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Read (no migration)
|
||||
const afterRead = await transformBrunoConfigAfterRead(newConfig, '/test/path');
|
||||
|
||||
// Save (cleanup)
|
||||
const beforeSave = transformBrunoConfigBeforeSave(afterRead);
|
||||
|
||||
// Read again (should not change)
|
||||
const afterSecondRead = await transformBrunoConfigAfterRead(beforeSave, '/test/path');
|
||||
|
||||
expect(afterSecondRead.proxy).toEqual(newConfig.proxy);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -22,6 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.0",
|
||||
"@babel/preset-typescript": "^7.22.0",
|
||||
"@opencollection/types": "~0.5.0",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
|
||||
@@ -88,7 +88,8 @@ const buildPkce = (pkce?: boolean | null): OAuth2PKCE | undefined => {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return { enabled: Boolean(pkce) };
|
||||
// If pkce is false, set disabled: true; if true, return empty object (enabled by default)
|
||||
return pkce ? {} : { disabled: true };
|
||||
};
|
||||
|
||||
const buildTokenConfig = (oauth: BrunoOAuth2): OAuth2TokenConfig | undefined => {
|
||||
@@ -540,8 +541,9 @@ export const toBrunoOAuth2 = (oauth: AuthOAuth2 | null | undefined): BrunoOAuth2
|
||||
|
||||
if (brunoOAuth.grantType === 'authorization_code' && oauth.flow === 'authorization_code') {
|
||||
const authCodeFlow = oauth as OAuth2AuthorizationCodeFlow;
|
||||
if (authCodeFlow.pkce?.enabled !== undefined) {
|
||||
brunoOAuth.pkce = authCodeFlow.pkce.enabled;
|
||||
if (authCodeFlow.pkce !== undefined) {
|
||||
// If pkce.disabled is true, set pkce to false; otherwise set to true
|
||||
brunoOAuth.pkce = !authCodeFlow.pkce.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,43 +50,53 @@ const parseCollection = (ymlString: string): ParsedCollection => {
|
||||
};
|
||||
}
|
||||
|
||||
// proxy
|
||||
// proxy - only support newer format
|
||||
// Default: inherit from global preferences
|
||||
brunoConfig.proxy = {
|
||||
enabled: false,
|
||||
protocol: '',
|
||||
hostname: '',
|
||||
port: '',
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
inherit: true,
|
||||
config: {
|
||||
protocol: 'http',
|
||||
hostname: '',
|
||||
port: '',
|
||||
auth: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
bypassProxy: ''
|
||||
}
|
||||
};
|
||||
|
||||
if (oc.config?.proxy) {
|
||||
if (oc.config.proxy === 'inherit') {
|
||||
brunoConfig.proxy.enabled = 'global';
|
||||
} else if (typeof oc.config.proxy === 'object') {
|
||||
if (oc.config?.proxy && typeof oc.config.proxy === 'object') {
|
||||
// Validate newer format: must have 'inherit' and 'config' properties
|
||||
const proxyConfig = oc.config.proxy as any;
|
||||
|
||||
if ('inherit' in proxyConfig && typeof proxyConfig.inherit === 'boolean' && proxyConfig.config && typeof proxyConfig.config === 'object') {
|
||||
// Valid newer format
|
||||
brunoConfig.proxy = {
|
||||
enabled: true,
|
||||
protocol: oc.config.proxy.protocol || '',
|
||||
hostname: oc.config.proxy.hostname || '',
|
||||
port: oc.config.proxy.port || '',
|
||||
auth: {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
inherit: proxyConfig.inherit,
|
||||
config: {
|
||||
protocol: proxyConfig.config.protocol || 'http',
|
||||
hostname: proxyConfig.config.hostname || '',
|
||||
port: proxyConfig.config.port || '',
|
||||
auth: {
|
||||
username: proxyConfig.config.auth?.username || '',
|
||||
password: proxyConfig.config.auth?.password || ''
|
||||
},
|
||||
bypassProxy: proxyConfig.config.bypassProxy || ''
|
||||
}
|
||||
};
|
||||
|
||||
if (oc.config.proxy.auth && typeof oc.config.proxy.auth === 'object') {
|
||||
brunoConfig.proxy.auth = {
|
||||
enabled: true,
|
||||
username: oc.config.proxy.auth.username || '',
|
||||
password: oc.config.proxy.auth.password || ''
|
||||
};
|
||||
// Handle optional disabled field
|
||||
if (proxyConfig.disabled === true) {
|
||||
brunoConfig.proxy.disabled = true;
|
||||
}
|
||||
|
||||
// Handle optional auth.disabled field
|
||||
if (proxyConfig.config.auth?.disabled === true) {
|
||||
brunoConfig.proxy.config.auth.disabled = true;
|
||||
}
|
||||
}
|
||||
// If not in newer format, use default (inherit: true)
|
||||
}
|
||||
|
||||
// client certificates
|
||||
|
||||
@@ -18,8 +18,15 @@ const hasCollectionConfig = (brunoConfig: any): boolean => {
|
||||
|| brunoConfig.protobuf?.importPaths?.length > 0
|
||||
);
|
||||
|
||||
// proxy
|
||||
const hasProxy = !!brunoConfig.proxy?.enabled;
|
||||
// proxy - check if proxy is configured in newer format
|
||||
// Valid newer format: has 'inherit' property and 'config' object
|
||||
const isValidProxyFormat = brunoConfig.proxy
|
||||
&& typeof brunoConfig.proxy === 'object'
|
||||
&& 'inherit' in brunoConfig.proxy
|
||||
&& brunoConfig.proxy.config
|
||||
&& typeof brunoConfig.proxy.config === 'object';
|
||||
|
||||
const hasProxy = isValidProxyFormat;
|
||||
|
||||
// client certificates
|
||||
const hasClientCertificates = brunoConfig.clientCertificates?.certs?.length > 0;
|
||||
@@ -52,7 +59,6 @@ const hasPresets = (brunoConfig: any): boolean => {
|
||||
};
|
||||
|
||||
const stringifyCollection = (collectionRoot: any, brunoConfig: any): string => {
|
||||
console.log('brunoConfig', brunoConfig);
|
||||
try {
|
||||
const oc: OpenCollection = {};
|
||||
|
||||
@@ -78,22 +84,38 @@ const stringifyCollection = (collectionRoot: any, brunoConfig: any): string => {
|
||||
};
|
||||
}
|
||||
|
||||
// proxy
|
||||
if (brunoConfig.proxy?.enabled) {
|
||||
if (brunoConfig.proxy.enabled === 'global') {
|
||||
oc.config.proxy = 'inherit';
|
||||
} else {
|
||||
oc.config.proxy = {
|
||||
protocol: brunoConfig.proxy.protocol,
|
||||
hostname: brunoConfig.proxy.hostname,
|
||||
port: brunoConfig.proxy.port
|
||||
};
|
||||
// proxy - only write newer format
|
||||
// Validate that brunoConfig.proxy is in newer format before writing
|
||||
const isValidProxyFormat = brunoConfig.proxy
|
||||
&& typeof brunoConfig.proxy === 'object'
|
||||
&& 'inherit' in brunoConfig.proxy
|
||||
&& brunoConfig.proxy.config
|
||||
&& typeof brunoConfig.proxy.config === 'object';
|
||||
|
||||
if (brunoConfig.proxy.auth?.enabled) {
|
||||
oc.config.proxy.auth = {
|
||||
username: brunoConfig.proxy.auth.username,
|
||||
password: brunoConfig.proxy.auth.password
|
||||
};
|
||||
if (isValidProxyFormat) {
|
||||
oc.config.proxy = {
|
||||
inherit: brunoConfig.proxy.inherit,
|
||||
config: {
|
||||
protocol: brunoConfig.proxy.config.protocol || 'http',
|
||||
hostname: brunoConfig.proxy.config.hostname || '',
|
||||
port: brunoConfig.proxy.config.port || '',
|
||||
auth: {
|
||||
username: brunoConfig.proxy.config.auth?.username || '',
|
||||
password: brunoConfig.proxy.config.auth?.password || ''
|
||||
},
|
||||
bypassProxy: brunoConfig.proxy.config.bypassProxy || ''
|
||||
}
|
||||
};
|
||||
|
||||
// Add optional disabled field if true
|
||||
if (brunoConfig.proxy.disabled === true) {
|
||||
oc.config.proxy.disabled = true;
|
||||
}
|
||||
|
||||
// Add optional auth.disabled field if true
|
||||
if (brunoConfig.proxy.config?.auth?.disabled === true) {
|
||||
if (oc.config.proxy.config && oc.config.proxy.config.auth) {
|
||||
oc.config.proxy.config.auth.disabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user